LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - basictz.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 315 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : * Copyright (C) 2007-2013, International Business Machines Corporation and
       6             : * others. All Rights Reserved.
       7             : *******************************************************************************
       8             : */
       9             : 
      10             : #include "unicode/utypes.h"
      11             : 
      12             : #if !UCONFIG_NO_FORMATTING
      13             : 
      14             : #include "unicode/basictz.h"
      15             : #include "gregoimp.h"
      16             : #include "uvector.h"
      17             : #include "cmemory.h"
      18             : 
      19             : U_NAMESPACE_BEGIN
      20             : 
      21             : #define MILLIS_PER_YEAR (365*24*60*60*1000.0)
      22             : 
      23           0 : BasicTimeZone::BasicTimeZone()
      24           0 : : TimeZone() {
      25           0 : }
      26             : 
      27           0 : BasicTimeZone::BasicTimeZone(const UnicodeString &id)
      28           0 : : TimeZone(id) {
      29           0 : }
      30             : 
      31           0 : BasicTimeZone::BasicTimeZone(const BasicTimeZone& source)
      32           0 : : TimeZone(source) {
      33           0 : }
      34             : 
      35           0 : BasicTimeZone::~BasicTimeZone() {
      36           0 : }
      37             : 
      38             : UBool
      39           0 : BasicTimeZone::hasEquivalentTransitions(const BasicTimeZone& tz, UDate start, UDate end,
      40             :                                         UBool ignoreDstAmount, UErrorCode& status) const {
      41           0 :     if (U_FAILURE(status)) {
      42           0 :         return FALSE;
      43             :     }
      44           0 :     if (hasSameRules(tz)) {
      45           0 :         return TRUE;
      46             :     }
      47             :     // Check the offsets at the start time
      48             :     int32_t raw1, raw2, dst1, dst2;
      49           0 :     getOffset(start, FALSE, raw1, dst1, status);
      50           0 :     if (U_FAILURE(status)) {
      51           0 :         return FALSE;
      52             :     }
      53           0 :     tz.getOffset(start, FALSE, raw2, dst2, status);
      54           0 :     if (U_FAILURE(status)) {
      55           0 :         return FALSE;
      56             :     }
      57           0 :     if (ignoreDstAmount) {
      58           0 :         if ((raw1 + dst1 != raw2 + dst2)
      59           0 :             || (dst1 != 0 && dst2 == 0)
      60           0 :             || (dst1 == 0 && dst2 != 0)) {
      61           0 :             return FALSE;
      62             :         }
      63             :     } else {
      64           0 :         if (raw1 != raw2 || dst1 != dst2) {
      65           0 :             return FALSE;
      66             :         }            
      67             :     }
      68             :     // Check transitions in the range
      69           0 :     UDate time = start;
      70           0 :     TimeZoneTransition tr1, tr2;
      71             :     while (TRUE) {
      72           0 :         UBool avail1 = getNextTransition(time, FALSE, tr1);
      73           0 :         UBool avail2 = tz.getNextTransition(time, FALSE, tr2);
      74             : 
      75           0 :         if (ignoreDstAmount) {
      76             :             // Skip a transition which only differ the amount of DST savings
      77             :             while (TRUE) {
      78           0 :                 if (avail1
      79           0 :                         && tr1.getTime() <= end
      80           0 :                         && (tr1.getFrom()->getRawOffset() + tr1.getFrom()->getDSTSavings()
      81           0 :                                 == tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings())
      82           0 :                         && (tr1.getFrom()->getDSTSavings() != 0 && tr1.getTo()->getDSTSavings() != 0)) {
      83           0 :                     getNextTransition(tr1.getTime(), FALSE, tr1);
      84             :                 } else {
      85           0 :                     break;
      86             :                 }
      87             :             }
      88             :             while (TRUE) {
      89           0 :                 if (avail2
      90           0 :                         && tr2.getTime() <= end
      91           0 :                         && (tr2.getFrom()->getRawOffset() + tr2.getFrom()->getDSTSavings()
      92           0 :                                 == tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings())
      93           0 :                         && (tr2.getFrom()->getDSTSavings() != 0 && tr2.getTo()->getDSTSavings() != 0)) {
      94           0 :                     tz.getNextTransition(tr2.getTime(), FALSE, tr2);
      95             :                 } else {
      96           0 :                     break;
      97             :                 }
      98             :             }
      99             :         }
     100             : 
     101           0 :         UBool inRange1 = (avail1 && tr1.getTime() <= end);
     102           0 :         UBool inRange2 = (avail2 && tr2.getTime() <= end);
     103           0 :         if (!inRange1 && !inRange2) {
     104             :             // No more transition in the range
     105           0 :             break;
     106             :         }
     107           0 :         if (!inRange1 || !inRange2) {
     108           0 :             return FALSE;
     109             :         }
     110           0 :         if (tr1.getTime() != tr2.getTime()) {
     111           0 :             return FALSE;
     112             :         }
     113           0 :         if (ignoreDstAmount) {
     114           0 :             if (tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings()
     115           0 :                         != tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings()
     116           0 :                     || (tr1.getTo()->getDSTSavings() != 0 &&  tr2.getTo()->getDSTSavings() == 0)
     117           0 :                     || (tr1.getTo()->getDSTSavings() == 0 &&  tr2.getTo()->getDSTSavings() != 0)) {
     118           0 :                 return FALSE;
     119             :             }
     120             :         } else {
     121           0 :             if (tr1.getTo()->getRawOffset() != tr2.getTo()->getRawOffset() ||
     122           0 :                 tr1.getTo()->getDSTSavings() != tr2.getTo()->getDSTSavings()) {
     123           0 :                 return FALSE;
     124             :             }
     125             :         }
     126           0 :         time = tr1.getTime();
     127           0 :     }
     128           0 :     return TRUE;
     129             : }
     130             : 
     131             : void
     132           0 : BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
     133             :         AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const {
     134           0 :     initial = NULL;
     135           0 :     std = NULL;
     136           0 :     dst = NULL;
     137           0 :     if (U_FAILURE(status)) {
     138           0 :         return;
     139             :     }
     140             :     int32_t initialRaw, initialDst;
     141           0 :     UnicodeString initialName;
     142             : 
     143           0 :     AnnualTimeZoneRule *ar1 = NULL;
     144           0 :     AnnualTimeZoneRule *ar2 = NULL;
     145           0 :     UnicodeString name;
     146             : 
     147             :     UBool avail;
     148           0 :     TimeZoneTransition tr;
     149             :     // Get the next transition
     150           0 :     avail = getNextTransition(date, FALSE, tr);
     151           0 :     if (avail) {
     152           0 :         tr.getFrom()->getName(initialName);
     153           0 :         initialRaw = tr.getFrom()->getRawOffset();
     154           0 :         initialDst = tr.getFrom()->getDSTSavings();
     155             : 
     156             :         // Check if the next transition is either DST->STD or STD->DST and
     157             :         // within roughly 1 year from the specified date
     158           0 :         UDate nextTransitionTime = tr.getTime();
     159           0 :         if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
     160           0 :               || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0))
     161           0 :             && (date + MILLIS_PER_YEAR > nextTransitionTime)) {
     162             :  
     163             :             int32_t year, month, dom, dow, doy, mid;
     164             :             UDate d;
     165             : 
     166             :             // Get local wall time for the next transition time
     167           0 :             Grego::timeToFields(nextTransitionTime + initialRaw + initialDst,
     168           0 :                 year, month, dom, dow, doy, mid);
     169           0 :             int32_t weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
     170             :             // Create DOW rule
     171           0 :             DateTimeRule *dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
     172           0 :             tr.getTo()->getName(name);
     173             : 
     174             :             // Note:  SimpleTimeZone does not support raw offset change.
     175             :             // So we always use raw offset of the given time for the rule,
     176             :             // even raw offset is changed.  This will result that the result
     177             :             // zone to return wrong offset after the transition.
     178             :             // When we encounter such case, we do not inspect next next
     179             :             // transition for another rule.
     180           0 :             ar1 = new AnnualTimeZoneRule(name, initialRaw, tr.getTo()->getDSTSavings(),
     181           0 :                 dtr, year, AnnualTimeZoneRule::MAX_YEAR);
     182             : 
     183           0 :             if (tr.getTo()->getRawOffset() == initialRaw) {
     184             :                 // Get the next next transition
     185           0 :                 avail = getNextTransition(nextTransitionTime, FALSE, tr);
     186           0 :                 if (avail) {
     187             :                     // Check if the next next transition is either DST->STD or STD->DST
     188             :                     // and within roughly 1 year from the next transition
     189           0 :                     if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
     190           0 :                           || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0))
     191           0 :                          && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) {
     192             : 
     193             :                         // Get local wall time for the next transition time
     194           0 :                         Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(),
     195           0 :                             year, month, dom, dow, doy, mid);
     196           0 :                         weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
     197             :                         // Generate another DOW rule
     198           0 :                         dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
     199           0 :                         tr.getTo()->getName(name);
     200           0 :                         ar2 = new AnnualTimeZoneRule(name, tr.getTo()->getRawOffset(), tr.getTo()->getDSTSavings(),
     201           0 :                             dtr, year - 1, AnnualTimeZoneRule::MAX_YEAR);
     202             : 
     203             :                         // Make sure this rule can be applied to the specified date
     204           0 :                         avail = ar2->getPreviousStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), TRUE, d);
     205           0 :                         if (!avail || d > date
     206           0 :                                 || initialRaw != tr.getTo()->getRawOffset()
     207           0 :                                 || initialDst != tr.getTo()->getDSTSavings()) {
     208             :                             // We cannot use this rule as the second transition rule
     209           0 :                             delete ar2;
     210           0 :                             ar2 = NULL;
     211             :                         }
     212             :                     }
     213             :                 }
     214             :             }
     215           0 :             if (ar2 == NULL) {
     216             :                 // Try previous transition
     217           0 :                 avail = getPreviousTransition(date, TRUE, tr);
     218           0 :                 if (avail) {
     219             :                     // Check if the previous transition is either DST->STD or STD->DST.
     220             :                     // The actual transition time does not matter here.
     221           0 :                     if ((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
     222           0 :                         || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0)) {
     223             : 
     224             :                         // Generate another DOW rule
     225           0 :                         Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(),
     226           0 :                             year, month, dom, dow, doy, mid);
     227           0 :                         weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
     228           0 :                         dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
     229           0 :                         tr.getTo()->getName(name);
     230             : 
     231             :                         // second rule raw/dst offsets should match raw/dst offsets
     232             :                         // at the given time
     233           0 :                         ar2 = new AnnualTimeZoneRule(name, initialRaw, initialDst,
     234           0 :                             dtr, ar1->getStartYear() - 1, AnnualTimeZoneRule::MAX_YEAR);
     235             : 
     236             :                         // Check if this rule start after the first rule after the specified date
     237           0 :                         avail = ar2->getNextStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), FALSE, d);
     238           0 :                         if (!avail || d <= nextTransitionTime) {
     239             :                             // We cannot use this rule as the second transition rule
     240           0 :                             delete ar2;
     241           0 :                             ar2 = NULL;
     242             :                         }
     243             :                     }
     244             :                 }
     245             :             }
     246           0 :             if (ar2 == NULL) {
     247             :                 // Cannot find a good pair of AnnualTimeZoneRule
     248           0 :                 delete ar1;
     249           0 :                 ar1 = NULL;
     250             :             } else {
     251             :                 // The initial rule should represent the rule before the previous transition
     252           0 :                 ar1->getName(initialName);
     253           0 :                 initialRaw = ar1->getRawOffset();
     254           0 :                 initialDst = ar1->getDSTSavings();
     255             :             }
     256             :         }
     257             :     }
     258             :     else {
     259             :         // Try the previous one
     260           0 :         avail = getPreviousTransition(date, TRUE, tr);
     261           0 :         if (avail) {
     262           0 :             tr.getTo()->getName(initialName);
     263           0 :             initialRaw = tr.getTo()->getRawOffset();
     264           0 :             initialDst = tr.getTo()->getDSTSavings();
     265             :         } else {
     266             :             // No transitions in the past.  Just use the current offsets
     267           0 :             getOffset(date, FALSE, initialRaw, initialDst, status);
     268           0 :             if (U_FAILURE(status)) {
     269           0 :                 return;
     270             :             }
     271             :         }
     272             :     }
     273             :     // Set the initial rule
     274           0 :     initial = new InitialTimeZoneRule(initialName, initialRaw, initialDst);
     275             : 
     276             :     // Set the standard and daylight saving rules
     277           0 :     if (ar1 != NULL && ar2 != NULL) {
     278           0 :         if (ar1->getDSTSavings() != 0) {
     279           0 :             dst = ar1;
     280           0 :             std = ar2;
     281             :         } else {
     282           0 :             std = ar1;
     283           0 :             dst = ar2;
     284             :         }
     285             :     }
     286             : }
     287             : 
     288             : void
     289           0 : BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial,
     290             :                                      UVector*& transitionRules, UErrorCode& status) const {
     291           0 :     if (U_FAILURE(status)) {
     292           0 :         return;
     293             :     }
     294             : 
     295             :     const InitialTimeZoneRule *orgini;
     296           0 :     const TimeZoneRule **orgtrs = NULL;
     297           0 :     TimeZoneTransition tzt;
     298             :     UBool avail;
     299           0 :     UVector *orgRules = NULL;
     300             :     int32_t ruleCount;
     301           0 :     TimeZoneRule *r = NULL;
     302           0 :     UBool *done = NULL;
     303           0 :     InitialTimeZoneRule *res_initial = NULL;
     304           0 :     UVector *filteredRules = NULL;
     305           0 :     UnicodeString name;
     306             :     int32_t i;
     307             :     UDate time, t;
     308           0 :     UDate *newTimes = NULL;
     309             :     UDate firstStart;
     310           0 :     UBool bFinalStd = FALSE, bFinalDst = FALSE;
     311             : 
     312             :     // Original transition rules
     313           0 :     ruleCount = countTransitionRules(status);
     314           0 :     if (U_FAILURE(status)) {
     315           0 :         return;
     316             :     }
     317           0 :     orgRules = new UVector(ruleCount, status);
     318           0 :     if (U_FAILURE(status)) {
     319           0 :         return;
     320             :     }
     321           0 :     orgtrs = (const TimeZoneRule**)uprv_malloc(sizeof(TimeZoneRule*)*ruleCount);
     322           0 :     if (orgtrs == NULL) {
     323           0 :         status = U_MEMORY_ALLOCATION_ERROR;
     324           0 :         goto error;
     325             :     }
     326           0 :     getTimeZoneRules(orgini, orgtrs, ruleCount, status);
     327           0 :     if (U_FAILURE(status)) {
     328           0 :         goto error;
     329             :     }
     330           0 :     for (i = 0; i < ruleCount; i++) {
     331           0 :         orgRules->addElement(orgtrs[i]->clone(), status);
     332           0 :         if (U_FAILURE(status)) {
     333           0 :             goto error;
     334             :         }
     335             :     }
     336           0 :     uprv_free(orgtrs);
     337           0 :     orgtrs = NULL;
     338             : 
     339           0 :     avail = getPreviousTransition(start, TRUE, tzt);
     340           0 :     if (!avail) {
     341             :         // No need to filter out rules only applicable to time before the start
     342           0 :         initial = orgini->clone();
     343           0 :         transitionRules = orgRules;
     344           0 :         return;
     345             :     }
     346             : 
     347           0 :     done = (UBool*)uprv_malloc(sizeof(UBool)*ruleCount);
     348           0 :     if (done == NULL) {
     349           0 :         status = U_MEMORY_ALLOCATION_ERROR;
     350           0 :         goto error;
     351             :     }
     352           0 :     filteredRules = new UVector(status);
     353           0 :     if (U_FAILURE(status)) {
     354           0 :         goto error;
     355             :     }
     356             : 
     357             :     // Create initial rule
     358           0 :     tzt.getTo()->getName(name);
     359           0 :     res_initial = new InitialTimeZoneRule(name, tzt.getTo()->getRawOffset(),
     360           0 :         tzt.getTo()->getDSTSavings());
     361             : 
     362             :     // Mark rules which does not need to be processed
     363           0 :     for (i = 0; i < ruleCount; i++) {
     364           0 :         r = (TimeZoneRule*)orgRules->elementAt(i);
     365           0 :         avail = r->getNextStart(start, res_initial->getRawOffset(), res_initial->getDSTSavings(), FALSE, time);
     366           0 :         done[i] = !avail;
     367             :     }
     368             : 
     369           0 :     time = start;
     370           0 :     while (!bFinalStd || !bFinalDst) {
     371           0 :         avail = getNextTransition(time, FALSE, tzt);
     372           0 :         if (!avail) {
     373           0 :             break;
     374             :         }
     375           0 :         UDate updatedTime = tzt.getTime();
     376           0 :         if (updatedTime == time) {
     377             :             // Can get here if rules for start & end of daylight time have exactly
     378             :             // the same time.  
     379             :             // TODO:  fix getNextTransition() to prevent it?
     380           0 :             status = U_INVALID_STATE_ERROR;
     381           0 :             goto error;
     382             :         }
     383           0 :         time = updatedTime;
     384             :  
     385           0 :         const TimeZoneRule *toRule = tzt.getTo();
     386           0 :         for (i = 0; i < ruleCount; i++) {
     387           0 :             r = (TimeZoneRule*)orgRules->elementAt(i);
     388           0 :             if (*r == *toRule) {
     389           0 :                 break;
     390             :             }
     391             :         }
     392           0 :         if (i >= ruleCount) {
     393             :             // This case should never happen
     394           0 :             status = U_INVALID_STATE_ERROR;
     395           0 :             goto error;
     396             :         }
     397           0 :         if (done[i]) {
     398           0 :             continue;
     399             :         }
     400           0 :         const TimeArrayTimeZoneRule *tar = dynamic_cast<const TimeArrayTimeZoneRule *>(toRule);
     401             :         const AnnualTimeZoneRule *ar;
     402           0 :         if (tar != NULL) {
     403             :             // Get the previous raw offset and DST savings before the very first start time
     404           0 :             TimeZoneTransition tzt0;
     405           0 :             t = start;
     406             :             while (TRUE) {
     407           0 :                 avail = getNextTransition(t, FALSE, tzt0);
     408           0 :                 if (!avail) {
     409           0 :                     break;
     410             :                 }
     411           0 :                 if (*(tzt0.getTo()) == *tar) {
     412           0 :                     break;
     413             :                 }
     414           0 :                 t = tzt0.getTime();
     415             :             }
     416           0 :             if (avail) {
     417             :                 // Check if the entire start times to be added
     418           0 :                 tar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart);
     419           0 :                 if (firstStart > start) {
     420             :                     // Just add the rule as is
     421           0 :                     filteredRules->addElement(tar->clone(), status);
     422           0 :                     if (U_FAILURE(status)) {
     423           0 :                         goto error;
     424             :                     }
     425             :                 } else {
     426             :                     // Colllect transitions after the start time
     427             :                     int32_t startTimes;
     428             :                     DateTimeRule::TimeRuleType timeType;
     429             :                     int32_t idx;
     430             : 
     431           0 :                     startTimes = tar->countStartTimes();
     432           0 :                     timeType = tar->getTimeType();
     433           0 :                     for (idx = 0; idx < startTimes; idx++) {
     434           0 :                         tar->getStartTimeAt(idx, t);
     435           0 :                         if (timeType == DateTimeRule::STANDARD_TIME) {
     436           0 :                             t -= tzt.getFrom()->getRawOffset();
     437             :                         }
     438           0 :                         if (timeType == DateTimeRule::WALL_TIME) {
     439           0 :                             t -= tzt.getFrom()->getDSTSavings();
     440             :                         }
     441           0 :                         if (t > start) {
     442           0 :                             break;
     443             :                         }
     444             :                     }
     445           0 :                     int32_t asize = startTimes - idx;
     446           0 :                     if (asize > 0) {
     447           0 :                         newTimes = (UDate*)uprv_malloc(sizeof(UDate) * asize);
     448           0 :                         if (newTimes == NULL) {
     449           0 :                             status = U_MEMORY_ALLOCATION_ERROR;
     450           0 :                             goto error;
     451             :                         }
     452           0 :                         for (int32_t newidx = 0; newidx < asize; newidx++) {
     453           0 :                             tar->getStartTimeAt(idx + newidx, newTimes[newidx]);
     454           0 :                             if (U_FAILURE(status)) {
     455           0 :                                 uprv_free(newTimes);
     456           0 :                                 newTimes = NULL;
     457           0 :                                 goto error;
     458             :                             }
     459             :                         }
     460           0 :                         tar->getName(name);
     461             :                         TimeArrayTimeZoneRule *newTar = new TimeArrayTimeZoneRule(name,
     462           0 :                             tar->getRawOffset(), tar->getDSTSavings(), newTimes, asize, timeType);
     463           0 :                         uprv_free(newTimes);
     464           0 :                         filteredRules->addElement(newTar, status);
     465           0 :                         if (U_FAILURE(status)) {
     466           0 :                             goto error;
     467             :                         }
     468             :                     }
     469             :                 }
     470             :             }
     471           0 :         } else if ((ar = dynamic_cast<const AnnualTimeZoneRule *>(toRule)) != NULL) {
     472           0 :             ar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart);
     473           0 :             if (firstStart == tzt.getTime()) {
     474             :                 // Just add the rule as is
     475           0 :                 filteredRules->addElement(ar->clone(), status);
     476           0 :                 if (U_FAILURE(status)) {
     477           0 :                     goto error;
     478             :                 }
     479             :             } else {
     480             :                 // Calculate the transition year
     481             :                 int32_t year, month, dom, dow, doy, mid;
     482           0 :                 Grego::timeToFields(tzt.getTime(), year, month, dom, dow, doy, mid);
     483             :                 // Re-create the rule
     484           0 :                 ar->getName(name);
     485           0 :                 AnnualTimeZoneRule *newAr = new AnnualTimeZoneRule(name, ar->getRawOffset(), ar->getDSTSavings(),
     486           0 :                     *(ar->getRule()), year, ar->getEndYear());
     487           0 :                 filteredRules->addElement(newAr, status);
     488           0 :                 if (U_FAILURE(status)) {
     489           0 :                     goto error;
     490             :                 }
     491             :             }
     492             :             // check if this is a final rule
     493           0 :             if (ar->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
     494             :                 // After bot final standard and dst rules are processed,
     495             :                 // exit this while loop.
     496           0 :                 if (ar->getDSTSavings() == 0) {
     497           0 :                     bFinalStd = TRUE;
     498             :                 } else {
     499           0 :                     bFinalDst = TRUE;
     500             :                 }
     501             :             }
     502             :         }
     503           0 :         done[i] = TRUE;
     504             :     }
     505             : 
     506             :     // Set the results
     507           0 :     if (orgRules != NULL) {
     508           0 :         while (!orgRules->isEmpty()) {
     509           0 :             r = (TimeZoneRule*)orgRules->orphanElementAt(0);
     510           0 :             delete r;
     511             :         }
     512           0 :         delete orgRules;
     513             :     }
     514           0 :     if (done != NULL) {
     515           0 :         uprv_free(done);
     516             :     }
     517             : 
     518           0 :     initial = res_initial;
     519           0 :     transitionRules = filteredRules;
     520           0 :     return;
     521             : 
     522             : error:
     523           0 :     if (orgtrs != NULL) {
     524           0 :         uprv_free(orgtrs);
     525             :     }
     526           0 :     if (orgRules != NULL) {
     527           0 :         while (!orgRules->isEmpty()) {
     528           0 :             r = (TimeZoneRule*)orgRules->orphanElementAt(0);
     529           0 :             delete r;
     530             :         }
     531           0 :         delete orgRules;
     532             :     }
     533           0 :     if (done != NULL) {
     534           0 :         if (filteredRules != NULL) {
     535           0 :             while (!filteredRules->isEmpty()) {
     536           0 :                 r = (TimeZoneRule*)filteredRules->orphanElementAt(0);
     537           0 :                 delete r;
     538             :             }
     539           0 :             delete filteredRules;
     540             :         }
     541           0 :         delete res_initial;
     542           0 :         uprv_free(done);
     543             :     }
     544             : 
     545           0 :     initial = NULL;
     546           0 :     transitionRules = NULL;
     547             : }
     548             : 
     549             : void
     550           0 : BasicTimeZone::getOffsetFromLocal(UDate /*date*/, int32_t /*nonExistingTimeOpt*/, int32_t /*duplicatedTimeOpt*/,
     551             :                             int32_t& /*rawOffset*/, int32_t& /*dstOffset*/, UErrorCode& status) const {
     552           0 :     if (U_FAILURE(status)) {
     553           0 :         return;
     554             :     }
     555           0 :     status = U_UNSUPPORTED_ERROR;
     556             : }
     557             : 
     558             : U_NAMESPACE_END
     559             : 
     560             : #endif /* #if !UCONFIG_NO_FORMATTING */
     561             : 
     562             : //eof

Generated by: LCOV version 1.13