Home | History | Annotate | Download | only in i18n
      1 /*
      2 *******************************************************************************
      3 * Copyright (C) 1997-2015, International Business Machines Corporation and    *
      4 * others. All Rights Reserved.                                                *
      5 *******************************************************************************
      6 *
      7 * File DTFMTSYM.CPP
      8 *
      9 * Modification History:
     10 *
     11 *   Date        Name        Description
     12 *   02/19/97    aliu        Converted from java.
     13 *   07/21/98    stephen     Added getZoneIndex
     14 *                            Changed weekdays/short weekdays to be one-based
     15 *   06/14/99    stephen     Removed SimpleDateFormat::fgTimeZoneDataSuffix
     16 *   11/16/99    weiv        Added 'Y' and 'e' to fgPatternChars
     17 *   03/27/00    weiv        Keeping resource bundle around!
     18 *   06/30/05    emmons      Added eraNames, narrow month/day, standalone context
     19 *   10/12/05    emmons      Added setters for eraNames, month/day by width/context
     20 *******************************************************************************
     21 */
     22 #include "unicode/utypes.h"
     23 
     24 #if !UCONFIG_NO_FORMATTING
     25 #include "unicode/ustring.h"
     26 #include "unicode/localpointer.h"
     27 #include "unicode/dtfmtsym.h"
     28 #include "unicode/smpdtfmt.h"
     29 #include "unicode/msgfmt.h"
     30 #include "unicode/numsys.h"
     31 #include "unicode/tznames.h"
     32 #include "cpputils.h"
     33 #include "umutex.h"
     34 #include "cmemory.h"
     35 #include "cstring.h"
     36 #include "locbased.h"
     37 #include "gregoimp.h"
     38 #include "hash.h"
     39 #include "uresimp.h"
     40 #include "ureslocs.h"
     41 #include "shareddateformatsymbols.h"
     42 #include "unicode/calendar.h"
     43 #include "unifiedcache.h"
     44 
     45 // *****************************************************************************
     46 // class DateFormatSymbols
     47 // *****************************************************************************
     48 
     49 /**
     50  * These are static arrays we use only in the case where we have no
     51  * resource data.
     52  */
     53 
     54 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
     55 #define PATTERN_CHARS_LEN 36
     56 #else
     57 #define PATTERN_CHARS_LEN 35
     58 #endif
     59 
     60 /**
     61  * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
     62  * locales use the same these unlocalized pattern characters.
     63  */
     64 static const UChar gPatternChars[] = {
     65 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
     66     // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr:
     67 #else
     68     // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr
     69 #endif
     70     0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
     71     0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
     72     0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0x56,
     73 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
     74     0x55, 0x4F, 0x58, 0x78, 0x72, 0x3a, 0
     75 #else
     76     0x55, 0x4F, 0x58, 0x78, 0x72, 0
     77 #endif
     78 };
     79 
     80 /* length of an array */
     81 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
     82 
     83 //------------------------------------------------------
     84 // Strings of last resort.  These are only used if we have no resource
     85 // files.  They aren't designed for actual use, just for backup.
     86 
     87 // These are the month names and abbreviations of last resort.
     88 static const UChar gLastResortMonthNames[13][3] =
     89 {
     90     {0x0030, 0x0031, 0x0000}, /* "01" */
     91     {0x0030, 0x0032, 0x0000}, /* "02" */
     92     {0x0030, 0x0033, 0x0000}, /* "03" */
     93     {0x0030, 0x0034, 0x0000}, /* "04" */
     94     {0x0030, 0x0035, 0x0000}, /* "05" */
     95     {0x0030, 0x0036, 0x0000}, /* "06" */
     96     {0x0030, 0x0037, 0x0000}, /* "07" */
     97     {0x0030, 0x0038, 0x0000}, /* "08" */
     98     {0x0030, 0x0039, 0x0000}, /* "09" */
     99     {0x0031, 0x0030, 0x0000}, /* "10" */
    100     {0x0031, 0x0031, 0x0000}, /* "11" */
    101     {0x0031, 0x0032, 0x0000}, /* "12" */
    102     {0x0031, 0x0033, 0x0000}  /* "13" */
    103 };
    104 
    105 // These are the weekday names and abbreviations of last resort.
    106 static const UChar gLastResortDayNames[8][2] =
    107 {
    108     {0x0030, 0x0000}, /* "0" */
    109     {0x0031, 0x0000}, /* "1" */
    110     {0x0032, 0x0000}, /* "2" */
    111     {0x0033, 0x0000}, /* "3" */
    112     {0x0034, 0x0000}, /* "4" */
    113     {0x0035, 0x0000}, /* "5" */
    114     {0x0036, 0x0000}, /* "6" */
    115     {0x0037, 0x0000}  /* "7" */
    116 };
    117 
    118 // These are the quarter names and abbreviations of last resort.
    119 static const UChar gLastResortQuarters[4][2] =
    120 {
    121     {0x0031, 0x0000}, /* "1" */
    122     {0x0032, 0x0000}, /* "2" */
    123     {0x0033, 0x0000}, /* "3" */
    124     {0x0034, 0x0000}, /* "4" */
    125 };
    126 
    127 // These are the am/pm and BC/AD markers of last resort.
    128 static const UChar gLastResortAmPmMarkers[2][3] =
    129 {
    130     {0x0041, 0x004D, 0x0000}, /* "AM" */
    131     {0x0050, 0x004D, 0x0000}  /* "PM" */
    132 };
    133 
    134 static const UChar gLastResortEras[2][3] =
    135 {
    136     {0x0042, 0x0043, 0x0000}, /* "BC" */
    137     {0x0041, 0x0044, 0x0000}  /* "AD" */
    138 };
    139 
    140 /* Sizes for the last resort string arrays */
    141 typedef enum LastResortSize {
    142     kMonthNum = 13,
    143     kMonthLen = 3,
    144 
    145     kDayNum = 8,
    146     kDayLen = 2,
    147 
    148     kAmPmNum = 2,
    149     kAmPmLen = 3,
    150 
    151     kQuarterNum = 4,
    152     kQuarterLen = 2,
    153 
    154     kEraNum = 2,
    155     kEraLen = 3,
    156 
    157     kZoneNum = 5,
    158     kZoneLen = 4,
    159 
    160     kGmtHourNum = 4,
    161     kGmtHourLen = 10
    162 } LastResortSize;
    163 
    164 U_NAMESPACE_BEGIN
    165 
    166 SharedDateFormatSymbols::~SharedDateFormatSymbols() {
    167 }
    168 
    169 template<> U_I18N_API
    170 const SharedDateFormatSymbols *
    171         LocaleCacheKey<SharedDateFormatSymbols>::createObject(
    172                 const void */*unusedContext*/, UErrorCode &status) const {
    173     char type[256];
    174     Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status);
    175     if (U_FAILURE(status)) {
    176         return NULL;
    177     }
    178     SharedDateFormatSymbols *shared
    179             = new SharedDateFormatSymbols(fLoc, type, status);
    180     if (shared == NULL) {
    181         status = U_MEMORY_ALLOCATION_ERROR;
    182         return NULL;
    183     }
    184     if (U_FAILURE(status)) {
    185         delete shared;
    186         return NULL;
    187     }
    188     shared->addRef();
    189     return shared;
    190 }
    191 
    192 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)
    193 
    194 #define kSUPPLEMENTAL "supplementalData"
    195 
    196 /**
    197  * These are the tags we expect to see in normal resource bundle files associated
    198  * with a locale and calendar
    199  */
    200 static const char gErasTag[]="eras";
    201 static const char gCyclicNameSetsTag[]="cyclicNameSets";
    202 static const char gNameSetYearsTag[]="years";
    203 static const char gNameSetZodiacsTag[]="zodiacs";
    204 static const char gMonthNamesTag[]="monthNames";
    205 static const char gMonthPatternsTag[]="monthPatterns";
    206 static const char gDayNamesTag[]="dayNames";
    207 static const char gNamesWideTag[]="wide";
    208 static const char gNamesAbbrTag[]="abbreviated";
    209 static const char gNamesShortTag[]="short";
    210 static const char gNamesNarrowTag[]="narrow";
    211 static const char gNamesAllTag[]="all";
    212 static const char gNamesLeapTag[]="leap";
    213 static const char gNamesFormatTag[]="format";
    214 static const char gNamesStandaloneTag[]="stand-alone";
    215 static const char gNamesNumericTag[]="numeric";
    216 static const char gAmPmMarkersTag[]="AmPmMarkers";
    217 static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow";
    218 static const char gQuartersTag[]="quarters";
    219 static const char gNumberElementsTag[]="NumberElements";
    220 static const char gSymbolsTag[]="symbols";
    221 static const char gTimeSeparatorTag[]="timeSeparator";
    222 
    223 // static const char gZoneStringsTag[]="zoneStrings";
    224 
    225 // static const char gLocalPatternCharsTag[]="localPatternChars";
    226 
    227 static const char gContextTransformsTag[]="contextTransforms";
    228 
    229 static UMutex LOCK = U_MUTEX_INITIALIZER;
    230 
    231 /**
    232  * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
    233  * Work around this.
    234  */
    235 static inline UnicodeString* newUnicodeStringArray(size_t count) {
    236     return new UnicodeString[count ? count : 1];
    237 }
    238 
    239 //------------------------------------------------------
    240 
    241 DateFormatSymbols * U_EXPORT2
    242 DateFormatSymbols::createForLocale(
    243         const Locale& locale, UErrorCode &status) {
    244     const SharedDateFormatSymbols *shared = NULL;
    245     UnifiedCache::getByLocale(locale, shared, status);
    246     if (U_FAILURE(status)) {
    247         return NULL;
    248     }
    249     DateFormatSymbols *result = new DateFormatSymbols(shared->get());
    250     shared->removeRef();
    251     if (result == NULL) {
    252         status = U_MEMORY_ALLOCATION_ERROR;
    253         return NULL;
    254     }
    255     return result;
    256 }
    257 
    258 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
    259                                      UErrorCode& status)
    260     : UObject()
    261 {
    262   initializeData(locale, NULL,  status);
    263 }
    264 
    265 DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
    266     : UObject()
    267 {
    268   initializeData(Locale::getDefault(), NULL, status, TRUE);
    269 }
    270 
    271 
    272 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
    273                                      const char *type,
    274                                      UErrorCode& status)
    275     : UObject()
    276 {
    277   initializeData(locale, type,  status);
    278 }
    279 
    280 DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
    281     : UObject()
    282 {
    283   initializeData(Locale::getDefault(), type, status, TRUE);
    284 }
    285 
    286 DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
    287     : UObject(other)
    288 {
    289     copyData(other);
    290 }
    291 
    292 void
    293 DateFormatSymbols::assignArray(UnicodeString*& dstArray,
    294                                int32_t& dstCount,
    295                                const UnicodeString* srcArray,
    296                                int32_t srcCount)
    297 {
    298     // assignArray() is only called by copyData(), which in turn implements the
    299     // copy constructor and the assignment operator.
    300     // All strings in a DateFormatSymbols object are created in one of the following
    301     // three ways that all allow to safely use UnicodeString::fastCopyFrom():
    302     // - readonly-aliases from resource bundles
    303     // - readonly-aliases or allocated strings from constants
    304     // - safely cloned strings (with owned buffers) from setXYZ() functions
    305     //
    306     // Note that this is true for as long as DateFormatSymbols can be constructed
    307     // only from a locale bundle or set via the cloning API,
    308     // *and* for as long as all the strings are in *private* fields, preventing
    309     // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()).
    310     dstCount = srcCount;
    311     dstArray = newUnicodeStringArray(srcCount);
    312     if(dstArray != NULL) {
    313         int32_t i;
    314         for(i=0; i<srcCount; ++i) {
    315             dstArray[i].fastCopyFrom(srcArray[i]);
    316         }
    317     }
    318 }
    319 
    320 /**
    321  * Create a copy, in fZoneStrings, of the given zone strings array.  The
    322  * member variables fZoneStringsRowCount and fZoneStringsColCount should
    323  * be set already by the caller.
    324  */
    325 void
    326 DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
    327 {
    328     int32_t row, col;
    329     UBool failed = FALSE;
    330 
    331     fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
    332     if (fZoneStrings != NULL) {
    333         for (row=0; row<fZoneStringsRowCount; ++row)
    334         {
    335             fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount);
    336             if (fZoneStrings[row] == NULL) {
    337                 failed = TRUE;
    338                 break;
    339             }
    340             for (col=0; col<fZoneStringsColCount; ++col) {
    341                 // fastCopyFrom() - see assignArray comments
    342                 fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);
    343             }
    344         }
    345     }
    346     // If memory allocation failed, roll back and delete fZoneStrings
    347     if (failed) {
    348         for (int i = row; i >= 0; i--) {
    349             delete[] fZoneStrings[i];
    350         }
    351         uprv_free(fZoneStrings);
    352         fZoneStrings = NULL;
    353     }
    354 }
    355 
    356 /**
    357  * Copy all of the other's data to this.
    358  */
    359 void
    360 DateFormatSymbols::copyData(const DateFormatSymbols& other) {
    361     UErrorCode status = U_ZERO_ERROR;
    362     U_LOCALE_BASED(locBased, *this);
    363     locBased.setLocaleIDs(
    364         other.getLocale(ULOC_VALID_LOCALE, status),
    365         other.getLocale(ULOC_ACTUAL_LOCALE, status));
    366     assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
    367     assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
    368     assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);
    369     assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);
    370     assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);
    371     assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);
    372     assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount);
    373     assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount);
    374     assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount);
    375     assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount);
    376     assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount);
    377     assignArray(fShorterWeekdays, fShorterWeekdaysCount, other.fShorterWeekdays, other.fShorterWeekdaysCount);
    378     assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount);
    379     assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount);
    380     assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount);
    381     assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount);
    382     assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);
    383     assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);
    384     assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount );
    385     fTimeSeparator.fastCopyFrom(other.fTimeSeparator);  // fastCopyFrom() - see assignArray comments
    386     assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);
    387     assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);
    388     assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount);
    389     assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount);
    390     if (other.fLeapMonthPatterns != NULL) {
    391         assignArray(fLeapMonthPatterns, fLeapMonthPatternsCount, other.fLeapMonthPatterns, other.fLeapMonthPatternsCount);
    392     } else {
    393         fLeapMonthPatterns = NULL;
    394         fLeapMonthPatternsCount = 0;
    395     }
    396     if (other.fShortYearNames != NULL) {
    397         assignArray(fShortYearNames, fShortYearNamesCount, other.fShortYearNames, other.fShortYearNamesCount);
    398     } else {
    399         fShortYearNames = NULL;
    400         fShortYearNamesCount = 0;
    401     }
    402     if (other.fShortZodiacNames != NULL) {
    403         assignArray(fShortZodiacNames, fShortZodiacNamesCount, other.fShortZodiacNames, other.fShortZodiacNamesCount);
    404     } else {
    405         fShortZodiacNames = NULL;
    406         fShortZodiacNamesCount = 0;
    407     }
    408 
    409     if (other.fZoneStrings != NULL) {
    410         fZoneStringsColCount = other.fZoneStringsColCount;
    411         fZoneStringsRowCount = other.fZoneStringsRowCount;
    412         createZoneStrings((const UnicodeString**)other.fZoneStrings);
    413 
    414     } else {
    415         fZoneStrings = NULL;
    416         fZoneStringsColCount = 0;
    417         fZoneStringsRowCount = 0;
    418     }
    419     fZSFLocale = other.fZSFLocale;
    420     // Other zone strings data is created on demand
    421     fLocaleZoneStrings = NULL;
    422 
    423     // fastCopyFrom() - see assignArray comments
    424     fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);
    425 
    426     uprv_memcpy(fCapitalization, other.fCapitalization, sizeof(fCapitalization));
    427 }
    428 
    429 /**
    430  * Assignment operator.
    431  */
    432 DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
    433 {
    434     dispose();
    435     copyData(other);
    436 
    437     return *this;
    438 }
    439 
    440 DateFormatSymbols::~DateFormatSymbols()
    441 {
    442     dispose();
    443 }
    444 
    445 void DateFormatSymbols::dispose()
    446 {
    447     if (fEras)                      delete[] fEras;
    448     if (fEraNames)                  delete[] fEraNames;
    449     if (fNarrowEras)                delete[] fNarrowEras;
    450     if (fMonths)                    delete[] fMonths;
    451     if (fShortMonths)               delete[] fShortMonths;
    452     if (fNarrowMonths)              delete[] fNarrowMonths;
    453     if (fStandaloneMonths)          delete[] fStandaloneMonths;
    454     if (fStandaloneShortMonths)     delete[] fStandaloneShortMonths;
    455     if (fStandaloneNarrowMonths)    delete[] fStandaloneNarrowMonths;
    456     if (fWeekdays)                  delete[] fWeekdays;
    457     if (fShortWeekdays)             delete[] fShortWeekdays;
    458     if (fShorterWeekdays)           delete[] fShorterWeekdays;
    459     if (fNarrowWeekdays)            delete[] fNarrowWeekdays;
    460     if (fStandaloneWeekdays)        delete[] fStandaloneWeekdays;
    461     if (fStandaloneShortWeekdays)   delete[] fStandaloneShortWeekdays;
    462     if (fStandaloneShorterWeekdays) delete[] fStandaloneShorterWeekdays;
    463     if (fStandaloneNarrowWeekdays)  delete[] fStandaloneNarrowWeekdays;
    464     if (fAmPms)                     delete[] fAmPms;
    465     if (fNarrowAmPms)               delete[] fNarrowAmPms;
    466     if (fQuarters)                  delete[] fQuarters;
    467     if (fShortQuarters)             delete[] fShortQuarters;
    468     if (fStandaloneQuarters)        delete[] fStandaloneQuarters;
    469     if (fStandaloneShortQuarters)   delete[] fStandaloneShortQuarters;
    470     if (fLeapMonthPatterns)         delete[] fLeapMonthPatterns;
    471     if (fShortYearNames)            delete[] fShortYearNames;
    472     if (fShortZodiacNames)          delete[] fShortZodiacNames;
    473 
    474     disposeZoneStrings();
    475 }
    476 
    477 void DateFormatSymbols::disposeZoneStrings()
    478 {
    479     if (fZoneStrings) {
    480         for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
    481             delete[] fZoneStrings[row];
    482         }
    483         uprv_free(fZoneStrings);
    484     }
    485     if (fLocaleZoneStrings) {
    486         for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
    487             delete[] fLocaleZoneStrings[row];
    488         }
    489         uprv_free(fLocaleZoneStrings);
    490     }
    491 
    492     fZoneStrings = NULL;
    493     fLocaleZoneStrings = NULL;
    494     fZoneStringsRowCount = 0;
    495     fZoneStringsColCount = 0;
    496 }
    497 
    498 UBool
    499 DateFormatSymbols::arrayCompare(const UnicodeString* array1,
    500                                 const UnicodeString* array2,
    501                                 int32_t count)
    502 {
    503     if (array1 == array2) return TRUE;
    504     while (count>0)
    505     {
    506         --count;
    507         if (array1[count] != array2[count]) return FALSE;
    508     }
    509     return TRUE;
    510 }
    511 
    512 UBool
    513 DateFormatSymbols::operator==(const DateFormatSymbols& other) const
    514 {
    515     // First do cheap comparisons
    516     if (this == &other) {
    517         return TRUE;
    518     }
    519     if (fErasCount == other.fErasCount &&
    520         fEraNamesCount == other.fEraNamesCount &&
    521         fNarrowErasCount == other.fNarrowErasCount &&
    522         fMonthsCount == other.fMonthsCount &&
    523         fShortMonthsCount == other.fShortMonthsCount &&
    524         fNarrowMonthsCount == other.fNarrowMonthsCount &&
    525         fStandaloneMonthsCount == other.fStandaloneMonthsCount &&
    526         fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount &&
    527         fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount &&
    528         fWeekdaysCount == other.fWeekdaysCount &&
    529         fShortWeekdaysCount == other.fShortWeekdaysCount &&
    530         fShorterWeekdaysCount == other.fShorterWeekdaysCount &&
    531         fNarrowWeekdaysCount == other.fNarrowWeekdaysCount &&
    532         fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount &&
    533         fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount &&
    534         fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount &&
    535         fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&
    536         fAmPmsCount == other.fAmPmsCount &&
    537         fNarrowAmPmsCount == other.fNarrowAmPmsCount &&
    538         fQuartersCount == other.fQuartersCount &&
    539         fShortQuartersCount == other.fShortQuartersCount &&
    540         fStandaloneQuartersCount == other.fStandaloneQuartersCount &&
    541         fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount &&
    542         fLeapMonthPatternsCount == other.fLeapMonthPatternsCount &&
    543         fShortYearNamesCount == other.fShortYearNamesCount &&
    544         fShortZodiacNamesCount == other.fShortZodiacNamesCount &&
    545         (uprv_memcmp(fCapitalization, other.fCapitalization, sizeof(fCapitalization))==0))
    546     {
    547         // Now compare the arrays themselves
    548         if (arrayCompare(fEras, other.fEras, fErasCount) &&
    549             arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&
    550             arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) &&
    551             arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
    552             arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
    553             arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&
    554             arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) &&
    555             arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) &&
    556             arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) &&
    557             arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&
    558             arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&
    559             arrayCompare(fShorterWeekdays, other.fShorterWeekdays, fShorterWeekdaysCount) &&
    560             arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) &&
    561             arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) &&
    562             arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) &&
    563             arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) &&
    564             arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&
    565             arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&
    566             arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) &&
    567             fTimeSeparator == other.fTimeSeparator &&
    568             arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&
    569             arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&
    570             arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) &&
    571             arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount) &&
    572             arrayCompare(fLeapMonthPatterns, other.fLeapMonthPatterns, fLeapMonthPatternsCount) &&
    573             arrayCompare(fShortYearNames, other.fShortYearNames, fShortYearNamesCount) &&
    574             arrayCompare(fShortZodiacNames, other.fShortZodiacNames, fShortZodiacNamesCount))
    575         {
    576             // Compare the contents of fZoneStrings
    577             if (fZoneStrings == NULL && other.fZoneStrings == NULL) {
    578                 if (fZSFLocale == other.fZSFLocale) {
    579                     return TRUE;
    580                 }
    581             } else if (fZoneStrings != NULL && other.fZoneStrings != NULL) {
    582                 if (fZoneStringsRowCount == other.fZoneStringsRowCount
    583                     && fZoneStringsColCount == other.fZoneStringsColCount) {
    584                     UBool cmpres = TRUE;
    585                     for (int32_t i = 0; (i < fZoneStringsRowCount) && cmpres; i++) {
    586                         cmpres = arrayCompare(fZoneStrings[i], other.fZoneStrings[i], fZoneStringsColCount);
    587                     }
    588                     return cmpres;
    589                 }
    590             }
    591             return FALSE;
    592         }
    593     }
    594     return FALSE;
    595 }
    596 
    597 //------------------------------------------------------
    598 
    599 const UnicodeString*
    600 DateFormatSymbols::getEras(int32_t &count) const
    601 {
    602     count = fErasCount;
    603     return fEras;
    604 }
    605 
    606 const UnicodeString*
    607 DateFormatSymbols::getEraNames(int32_t &count) const
    608 {
    609     count = fEraNamesCount;
    610     return fEraNames;
    611 }
    612 
    613 const UnicodeString*
    614 DateFormatSymbols::getNarrowEras(int32_t &count) const
    615 {
    616     count = fNarrowErasCount;
    617     return fNarrowEras;
    618 }
    619 
    620 const UnicodeString*
    621 DateFormatSymbols::getMonths(int32_t &count) const
    622 {
    623     count = fMonthsCount;
    624     return fMonths;
    625 }
    626 
    627 const UnicodeString*
    628 DateFormatSymbols::getShortMonths(int32_t &count) const
    629 {
    630     count = fShortMonthsCount;
    631     return fShortMonths;
    632 }
    633 
    634 const UnicodeString*
    635 DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const
    636 {
    637     UnicodeString *returnValue = NULL;
    638 
    639     switch (context) {
    640     case FORMAT :
    641         switch(width) {
    642         case WIDE :
    643             count = fMonthsCount;
    644             returnValue = fMonths;
    645             break;
    646         case ABBREVIATED :
    647         case SHORT : // no month data for this, defaults to ABBREVIATED
    648             count = fShortMonthsCount;
    649             returnValue = fShortMonths;
    650             break;
    651         case NARROW :
    652             count = fNarrowMonthsCount;
    653             returnValue = fNarrowMonths;
    654             break;
    655         case DT_WIDTH_COUNT :
    656             break;
    657         }
    658         break;
    659     case STANDALONE :
    660         switch(width) {
    661         case WIDE :
    662             count = fStandaloneMonthsCount;
    663             returnValue = fStandaloneMonths;
    664             break;
    665         case ABBREVIATED :
    666         case SHORT : // no month data for this, defaults to ABBREVIATED
    667             count = fStandaloneShortMonthsCount;
    668             returnValue = fStandaloneShortMonths;
    669             break;
    670         case NARROW :
    671             count = fStandaloneNarrowMonthsCount;
    672             returnValue = fStandaloneNarrowMonths;
    673             break;
    674         case DT_WIDTH_COUNT :
    675             break;
    676         }
    677         break;
    678     case DT_CONTEXT_COUNT :
    679         break;
    680     }
    681     return returnValue;
    682 }
    683 
    684 const UnicodeString*
    685 DateFormatSymbols::getWeekdays(int32_t &count) const
    686 {
    687     count = fWeekdaysCount;
    688     return fWeekdays;
    689 }
    690 
    691 const UnicodeString*
    692 DateFormatSymbols::getShortWeekdays(int32_t &count) const
    693 {
    694     count = fShortWeekdaysCount;
    695     return fShortWeekdays;
    696 }
    697 
    698 const UnicodeString*
    699 DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const
    700 {
    701     UnicodeString *returnValue = NULL;
    702     switch (context) {
    703     case FORMAT :
    704         switch(width) {
    705             case WIDE :
    706                 count = fWeekdaysCount;
    707                 returnValue = fWeekdays;
    708                 break;
    709             case ABBREVIATED :
    710                 count = fShortWeekdaysCount;
    711                 returnValue = fShortWeekdays;
    712                 break;
    713             case SHORT :
    714                 count = fShorterWeekdaysCount;
    715                 returnValue = fShorterWeekdays;
    716                 break;
    717             case NARROW :
    718                 count = fNarrowWeekdaysCount;
    719                 returnValue = fNarrowWeekdays;
    720                 break;
    721             case DT_WIDTH_COUNT :
    722                 break;
    723         }
    724         break;
    725     case STANDALONE :
    726         switch(width) {
    727             case WIDE :
    728                 count = fStandaloneWeekdaysCount;
    729                 returnValue = fStandaloneWeekdays;
    730                 break;
    731             case ABBREVIATED :
    732                 count = fStandaloneShortWeekdaysCount;
    733                 returnValue = fStandaloneShortWeekdays;
    734                 break;
    735             case SHORT :
    736                 count = fStandaloneShorterWeekdaysCount;
    737                 returnValue = fStandaloneShorterWeekdays;
    738                 break;
    739             case NARROW :
    740                 count = fStandaloneNarrowWeekdaysCount;
    741                 returnValue = fStandaloneNarrowWeekdays;
    742                 break;
    743             case DT_WIDTH_COUNT :
    744                 break;
    745         }
    746         break;
    747     case DT_CONTEXT_COUNT :
    748         break;
    749     }
    750     return returnValue;
    751 }
    752 
    753 const UnicodeString*
    754 DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const
    755 {
    756     UnicodeString *returnValue = NULL;
    757 
    758     switch (context) {
    759     case FORMAT :
    760         switch(width) {
    761         case WIDE :
    762             count = fQuartersCount;
    763             returnValue = fQuarters;
    764             break;
    765         case ABBREVIATED :
    766         case SHORT : // no quarter data for this, defaults to ABBREVIATED
    767             count = fShortQuartersCount;
    768             returnValue = fShortQuarters;
    769             break;
    770         case NARROW :
    771             count = 0;
    772             returnValue = NULL;
    773             break;
    774         case DT_WIDTH_COUNT :
    775             break;
    776         }
    777         break;
    778     case STANDALONE :
    779         switch(width) {
    780         case WIDE :
    781             count = fStandaloneQuartersCount;
    782             returnValue = fStandaloneQuarters;
    783             break;
    784         case ABBREVIATED :
    785         case SHORT : // no quarter data for this, defaults to ABBREVIATED
    786             count = fStandaloneShortQuartersCount;
    787             returnValue = fStandaloneShortQuarters;
    788             break;
    789         case NARROW :
    790             count = 0;
    791             returnValue = NULL;
    792             break;
    793         case DT_WIDTH_COUNT :
    794             break;
    795         }
    796         break;
    797     case DT_CONTEXT_COUNT :
    798         break;
    799     }
    800     return returnValue;
    801 }
    802 
    803 UnicodeString&
    804 DateFormatSymbols::getTimeSeparatorString(UnicodeString& result) const
    805 {
    806     // fastCopyFrom() - see assignArray comments
    807     return result.fastCopyFrom(fTimeSeparator);
    808 }
    809 
    810 const UnicodeString*
    811 DateFormatSymbols::getAmPmStrings(int32_t &count) const
    812 {
    813     count = fAmPmsCount;
    814     return fAmPms;
    815 }
    816 
    817 const UnicodeString*
    818 DateFormatSymbols::getLeapMonthPatterns(int32_t &count) const
    819 {
    820     count = fLeapMonthPatternsCount;
    821     return fLeapMonthPatterns;
    822 }
    823 
    824 const UnicodeString*
    825 DateFormatSymbols::getYearNames(int32_t& count,
    826                                 DtContextType /*ignored*/, DtWidthType /*ignored*/) const
    827 {
    828     count = fShortYearNamesCount;
    829     return fShortYearNames;
    830 }
    831 
    832 void
    833 DateFormatSymbols::setYearNames(const UnicodeString* yearNames, int32_t count,
    834                                 DtContextType context, DtWidthType width)
    835 {
    836     if (context == FORMAT && width == ABBREVIATED) {
    837         if (fShortYearNames) {
    838             delete[] fShortYearNames;
    839         }
    840         fShortYearNames = newUnicodeStringArray(count);
    841         uprv_arrayCopy(yearNames, fShortYearNames, count);
    842         fShortYearNamesCount = count;
    843     }
    844 }
    845 
    846 const UnicodeString*
    847 DateFormatSymbols::getZodiacNames(int32_t& count,
    848                                 DtContextType /*ignored*/, DtWidthType /*ignored*/) const
    849 {
    850     count = fShortZodiacNamesCount;
    851     return fShortZodiacNames;
    852 }
    853 
    854 void
    855 DateFormatSymbols::setZodiacNames(const UnicodeString* zodiacNames, int32_t count,
    856                                 DtContextType context, DtWidthType width)
    857 {
    858     if (context == FORMAT && width == ABBREVIATED) {
    859         if (fShortZodiacNames) {
    860             delete[] fShortZodiacNames;
    861         }
    862         fShortZodiacNames = newUnicodeStringArray(count);
    863         uprv_arrayCopy(zodiacNames, fShortZodiacNames, count);
    864         fShortZodiacNamesCount = count;
    865     }
    866 }
    867 
    868 //------------------------------------------------------
    869 
    870 void
    871 DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
    872 {
    873     // delete the old list if we own it
    874     if (fEras)
    875         delete[] fEras;
    876 
    877     // we always own the new list, which we create here (we duplicate rather
    878     // than adopting the list passed in)
    879     fEras = newUnicodeStringArray(count);
    880     uprv_arrayCopy(erasArray,fEras,  count);
    881     fErasCount = count;
    882 }
    883 
    884 void
    885 DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)
    886 {
    887     // delete the old list if we own it
    888     if (fEraNames)
    889         delete[] fEraNames;
    890 
    891     // we always own the new list, which we create here (we duplicate rather
    892     // than adopting the list passed in)
    893     fEraNames = newUnicodeStringArray(count);
    894     uprv_arrayCopy(eraNamesArray,fEraNames,  count);
    895     fEraNamesCount = count;
    896 }
    897 
    898 void
    899 DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)
    900 {
    901     // delete the old list if we own it
    902     if (fNarrowEras)
    903         delete[] fNarrowEras;
    904 
    905     // we always own the new list, which we create here (we duplicate rather
    906     // than adopting the list passed in)
    907     fNarrowEras = newUnicodeStringArray(count);
    908     uprv_arrayCopy(narrowErasArray,fNarrowEras,  count);
    909     fNarrowErasCount = count;
    910 }
    911 
    912 void
    913 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
    914 {
    915     // delete the old list if we own it
    916     if (fMonths)
    917         delete[] fMonths;
    918 
    919     // we always own the new list, which we create here (we duplicate rather
    920     // than adopting the list passed in)
    921     fMonths = newUnicodeStringArray(count);
    922     uprv_arrayCopy( monthsArray,fMonths,count);
    923     fMonthsCount = count;
    924 }
    925 
    926 void
    927 DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
    928 {
    929     // delete the old list if we own it
    930     if (fShortMonths)
    931         delete[] fShortMonths;
    932 
    933     // we always own the new list, which we create here (we duplicate rather
    934     // than adopting the list passed in)
    935     fShortMonths = newUnicodeStringArray(count);
    936     uprv_arrayCopy(shortMonthsArray,fShortMonths,  count);
    937     fShortMonthsCount = count;
    938 }
    939 
    940 void
    941 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)
    942 {
    943     // delete the old list if we own it
    944     // we always own the new list, which we create here (we duplicate rather
    945     // than adopting the list passed in)
    946 
    947     switch (context) {
    948     case FORMAT :
    949         switch (width) {
    950         case WIDE :
    951             if (fMonths)
    952                 delete[] fMonths;
    953             fMonths = newUnicodeStringArray(count);
    954             uprv_arrayCopy( monthsArray,fMonths,count);
    955             fMonthsCount = count;
    956             break;
    957         case ABBREVIATED :
    958             if (fShortMonths)
    959                 delete[] fShortMonths;
    960             fShortMonths = newUnicodeStringArray(count);
    961             uprv_arrayCopy( monthsArray,fShortMonths,count);
    962             fShortMonthsCount = count;
    963             break;
    964         case NARROW :
    965             if (fNarrowMonths)
    966                 delete[] fNarrowMonths;
    967             fNarrowMonths = newUnicodeStringArray(count);
    968             uprv_arrayCopy( monthsArray,fNarrowMonths,count);
    969             fNarrowMonthsCount = count;
    970             break;
    971         default :
    972             break;
    973         }
    974         break;
    975     case STANDALONE :
    976         switch (width) {
    977         case WIDE :
    978             if (fStandaloneMonths)
    979                 delete[] fStandaloneMonths;
    980             fStandaloneMonths = newUnicodeStringArray(count);
    981             uprv_arrayCopy( monthsArray,fStandaloneMonths,count);
    982             fStandaloneMonthsCount = count;
    983             break;
    984         case ABBREVIATED :
    985             if (fStandaloneShortMonths)
    986                 delete[] fStandaloneShortMonths;
    987             fStandaloneShortMonths = newUnicodeStringArray(count);
    988             uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count);
    989             fStandaloneShortMonthsCount = count;
    990             break;
    991         case NARROW :
    992            if (fStandaloneNarrowMonths)
    993                 delete[] fStandaloneNarrowMonths;
    994             fStandaloneNarrowMonths = newUnicodeStringArray(count);
    995             uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count);
    996             fStandaloneNarrowMonthsCount = count;
    997             break;
    998         default :
    999             break;
   1000         }
   1001         break;
   1002     case DT_CONTEXT_COUNT :
   1003         break;
   1004     }
   1005 }
   1006 
   1007 void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
   1008 {
   1009     // delete the old list if we own it
   1010     if (fWeekdays)
   1011         delete[] fWeekdays;
   1012 
   1013     // we always own the new list, which we create here (we duplicate rather
   1014     // than adopting the list passed in)
   1015     fWeekdays = newUnicodeStringArray(count);
   1016     uprv_arrayCopy(weekdaysArray,fWeekdays,count);
   1017     fWeekdaysCount = count;
   1018 }
   1019 
   1020 void
   1021 DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
   1022 {
   1023     // delete the old list if we own it
   1024     if (fShortWeekdays)
   1025         delete[] fShortWeekdays;
   1026 
   1027     // we always own the new list, which we create here (we duplicate rather
   1028     // than adopting the list passed in)
   1029     fShortWeekdays = newUnicodeStringArray(count);
   1030     uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);
   1031     fShortWeekdaysCount = count;
   1032 }
   1033 
   1034 void
   1035 DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)
   1036 {
   1037     // delete the old list if we own it
   1038     // we always own the new list, which we create here (we duplicate rather
   1039     // than adopting the list passed in)
   1040 
   1041     switch (context) {
   1042     case FORMAT :
   1043         switch (width) {
   1044         case WIDE :
   1045             if (fWeekdays)
   1046                 delete[] fWeekdays;
   1047             fWeekdays = newUnicodeStringArray(count);
   1048             uprv_arrayCopy(weekdaysArray, fWeekdays, count);
   1049             fWeekdaysCount = count;
   1050             break;
   1051         case ABBREVIATED :
   1052             if (fShortWeekdays)
   1053                 delete[] fShortWeekdays;
   1054             fShortWeekdays = newUnicodeStringArray(count);
   1055             uprv_arrayCopy(weekdaysArray, fShortWeekdays, count);
   1056             fShortWeekdaysCount = count;
   1057             break;
   1058         case SHORT :
   1059             if (fShorterWeekdays)
   1060                 delete[] fShorterWeekdays;
   1061             fShorterWeekdays = newUnicodeStringArray(count);
   1062             uprv_arrayCopy(weekdaysArray, fShorterWeekdays, count);
   1063             fShorterWeekdaysCount = count;
   1064             break;
   1065         case NARROW :
   1066             if (fNarrowWeekdays)
   1067                 delete[] fNarrowWeekdays;
   1068             fNarrowWeekdays = newUnicodeStringArray(count);
   1069             uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count);
   1070             fNarrowWeekdaysCount = count;
   1071             break;
   1072         case DT_WIDTH_COUNT :
   1073             break;
   1074         }
   1075         break;
   1076     case STANDALONE :
   1077         switch (width) {
   1078         case WIDE :
   1079             if (fStandaloneWeekdays)
   1080                 delete[] fStandaloneWeekdays;
   1081             fStandaloneWeekdays = newUnicodeStringArray(count);
   1082             uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count);
   1083             fStandaloneWeekdaysCount = count;
   1084             break;
   1085         case ABBREVIATED :
   1086             if (fStandaloneShortWeekdays)
   1087                 delete[] fStandaloneShortWeekdays;
   1088             fStandaloneShortWeekdays = newUnicodeStringArray(count);
   1089             uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count);
   1090             fStandaloneShortWeekdaysCount = count;
   1091             break;
   1092         case SHORT :
   1093             if (fStandaloneShorterWeekdays)
   1094                 delete[] fStandaloneShorterWeekdays;
   1095             fStandaloneShorterWeekdays = newUnicodeStringArray(count);
   1096             uprv_arrayCopy(weekdaysArray, fStandaloneShorterWeekdays, count);
   1097             fStandaloneShorterWeekdaysCount = count;
   1098             break;
   1099         case NARROW :
   1100             if (fStandaloneNarrowWeekdays)
   1101                 delete[] fStandaloneNarrowWeekdays;
   1102             fStandaloneNarrowWeekdays = newUnicodeStringArray(count);
   1103             uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count);
   1104             fStandaloneNarrowWeekdaysCount = count;
   1105             break;
   1106         case DT_WIDTH_COUNT :
   1107             break;
   1108         }
   1109         break;
   1110     case DT_CONTEXT_COUNT :
   1111         break;
   1112     }
   1113 }
   1114 
   1115 void
   1116 DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)
   1117 {
   1118     // delete the old list if we own it
   1119     // we always own the new list, which we create here (we duplicate rather
   1120     // than adopting the list passed in)
   1121 
   1122     switch (context) {
   1123     case FORMAT :
   1124         switch (width) {
   1125         case WIDE :
   1126             if (fQuarters)
   1127                 delete[] fQuarters;
   1128             fQuarters = newUnicodeStringArray(count);
   1129             uprv_arrayCopy( quartersArray,fQuarters,count);
   1130             fQuartersCount = count;
   1131             break;
   1132         case ABBREVIATED :
   1133             if (fShortQuarters)
   1134                 delete[] fShortQuarters;
   1135             fShortQuarters = newUnicodeStringArray(count);
   1136             uprv_arrayCopy( quartersArray,fShortQuarters,count);
   1137             fShortQuartersCount = count;
   1138             break;
   1139         case NARROW :
   1140         /*
   1141             if (fNarrowQuarters)
   1142                 delete[] fNarrowQuarters;
   1143             fNarrowQuarters = newUnicodeStringArray(count);
   1144             uprv_arrayCopy( quartersArray,fNarrowQuarters,count);
   1145             fNarrowQuartersCount = count;
   1146         */
   1147             break;
   1148         default :
   1149             break;
   1150         }
   1151         break;
   1152     case STANDALONE :
   1153         switch (width) {
   1154         case WIDE :
   1155             if (fStandaloneQuarters)
   1156                 delete[] fStandaloneQuarters;
   1157             fStandaloneQuarters = newUnicodeStringArray(count);
   1158             uprv_arrayCopy( quartersArray,fStandaloneQuarters,count);
   1159             fStandaloneQuartersCount = count;
   1160             break;
   1161         case ABBREVIATED :
   1162             if (fStandaloneShortQuarters)
   1163                 delete[] fStandaloneShortQuarters;
   1164             fStandaloneShortQuarters = newUnicodeStringArray(count);
   1165             uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count);
   1166             fStandaloneShortQuartersCount = count;
   1167             break;
   1168         case NARROW :
   1169         /*
   1170            if (fStandaloneNarrowQuarters)
   1171                 delete[] fStandaloneNarrowQuarters;
   1172             fStandaloneNarrowQuarters = newUnicodeStringArray(count);
   1173             uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count);
   1174             fStandaloneNarrowQuartersCount = count;
   1175         */
   1176             break;
   1177         default :
   1178             break;
   1179         }
   1180         break;
   1181     case DT_CONTEXT_COUNT :
   1182         break;
   1183     }
   1184 }
   1185 
   1186 void
   1187 DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
   1188 {
   1189     // delete the old list if we own it
   1190     if (fAmPms) delete[] fAmPms;
   1191 
   1192     // we always own the new list, which we create here (we duplicate rather
   1193     // than adopting the list passed in)
   1194     fAmPms = newUnicodeStringArray(count);
   1195     uprv_arrayCopy(amPmsArray,fAmPms,count);
   1196     fAmPmsCount = count;
   1197 }
   1198 
   1199 void
   1200 DateFormatSymbols::setTimeSeparatorString(const UnicodeString& newTimeSeparator)
   1201 {
   1202     fTimeSeparator = newTimeSeparator;
   1203 }
   1204 
   1205 const UnicodeString**
   1206 DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
   1207 {
   1208     const UnicodeString **result = NULL;
   1209 
   1210     umtx_lock(&LOCK);
   1211     if (fZoneStrings == NULL) {
   1212         if (fLocaleZoneStrings == NULL) {
   1213             ((DateFormatSymbols*)this)->initZoneStringsArray();
   1214         }
   1215         result = (const UnicodeString**)fLocaleZoneStrings;
   1216     } else {
   1217         result = (const UnicodeString**)fZoneStrings;
   1218     }
   1219     rowCount = fZoneStringsRowCount;
   1220     columnCount = fZoneStringsColCount;
   1221     umtx_unlock(&LOCK);
   1222 
   1223     return result;
   1224 }
   1225 
   1226 // For now, we include all zones
   1227 #define ZONE_SET UCAL_ZONE_TYPE_ANY
   1228 
   1229 // This code must be called within a synchronized block
   1230 void
   1231 DateFormatSymbols::initZoneStringsArray(void) {
   1232     if (fZoneStrings != NULL || fLocaleZoneStrings != NULL) {
   1233         return;
   1234     }
   1235 
   1236     UErrorCode status = U_ZERO_ERROR;
   1237 
   1238     StringEnumeration *tzids = NULL;
   1239     UnicodeString ** zarray = NULL;
   1240     TimeZoneNames *tzNames = NULL;
   1241     int32_t rows = 0;
   1242 
   1243     do { // dummy do-while
   1244 
   1245         tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status);
   1246         rows = tzids->count(status);
   1247         if (U_FAILURE(status)) {
   1248             break;
   1249         }
   1250 
   1251         // Allocate array
   1252         int32_t size = rows * sizeof(UnicodeString*);
   1253         zarray = (UnicodeString**)uprv_malloc(size);
   1254         if (zarray == NULL) {
   1255             status = U_MEMORY_ALLOCATION_ERROR;
   1256             break;
   1257         }
   1258         uprv_memset(zarray, 0, size);
   1259 
   1260         tzNames = TimeZoneNames::createInstance(fZSFLocale, status);
   1261 
   1262         const UnicodeString *tzid;
   1263         int32_t i = 0;
   1264         UDate now = Calendar::getNow();
   1265         UnicodeString tzDispName;
   1266 
   1267         while ((tzid = tzids->snext(status))) {
   1268             if (U_FAILURE(status)) {
   1269                 break;
   1270             }
   1271 
   1272             zarray[i] = new UnicodeString[5];
   1273             if (zarray[i] == NULL) {
   1274                 status = U_MEMORY_ALLOCATION_ERROR;
   1275                 break;
   1276             }
   1277 
   1278             zarray[i][0].setTo(*tzid);
   1279             zarray[i][1].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_STANDARD, now, tzDispName));
   1280             zarray[i][2].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_STANDARD, now, tzDispName));
   1281             zarray[i][3].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_DAYLIGHT, now, tzDispName));
   1282             zarray[i][4].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_DAYLIGHT, now, tzDispName));
   1283             i++;
   1284         }
   1285 
   1286     } while (FALSE);
   1287 
   1288     if (U_FAILURE(status)) {
   1289         if (zarray) {
   1290             for (int32_t i = 0; i < rows; i++) {
   1291                 if (zarray[i]) {
   1292                     delete[] zarray[i];
   1293                 }
   1294             }
   1295             uprv_free(zarray);
   1296         }
   1297     }
   1298 
   1299     if (tzNames) {
   1300         delete tzNames;
   1301     }
   1302     if (tzids) {
   1303         delete tzids;
   1304     }
   1305 
   1306     fLocaleZoneStrings = zarray;
   1307     fZoneStringsRowCount = rows;
   1308     fZoneStringsColCount = 5;
   1309 }
   1310 
   1311 void
   1312 DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)
   1313 {
   1314     // since deleting a 2-d array is a pain in the butt, we offload that task to
   1315     // a separate function
   1316     disposeZoneStrings();
   1317     // we always own the new list, which we create here (we duplicate rather
   1318     // than adopting the list passed in)
   1319     fZoneStringsRowCount = rowCount;
   1320     fZoneStringsColCount = columnCount;
   1321     createZoneStrings((const UnicodeString**)strings);
   1322 }
   1323 
   1324 //------------------------------------------------------
   1325 
   1326 const UChar * U_EXPORT2
   1327 DateFormatSymbols::getPatternUChars(void)
   1328 {
   1329     return gPatternChars;
   1330 }
   1331 
   1332 UDateFormatField U_EXPORT2
   1333 DateFormatSymbols::getPatternCharIndex(UChar c) {
   1334     const UChar *p = u_strchr(gPatternChars, c);
   1335     if (p == NULL) {
   1336         return UDAT_FIELD_COUNT;
   1337     } else {
   1338         return static_cast<UDateFormatField>(p - gPatternChars);
   1339     }
   1340 }
   1341 
   1342 static const uint64_t kNumericFieldsAlways =
   1343     ((uint64_t)1 << UDAT_YEAR_FIELD) |                      // y
   1344     ((uint64_t)1 << UDAT_DATE_FIELD) |                      // d
   1345     ((uint64_t)1 << UDAT_HOUR_OF_DAY1_FIELD) |              // k
   1346     ((uint64_t)1 << UDAT_HOUR_OF_DAY0_FIELD) |              // H
   1347     ((uint64_t)1 << UDAT_MINUTE_FIELD) |                    // m
   1348     ((uint64_t)1 << UDAT_SECOND_FIELD) |                    // s
   1349     ((uint64_t)1 << UDAT_FRACTIONAL_SECOND_FIELD) |         // S
   1350     ((uint64_t)1 << UDAT_DAY_OF_YEAR_FIELD) |               // D
   1351     ((uint64_t)1 << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) |      // F
   1352     ((uint64_t)1 << UDAT_WEEK_OF_YEAR_FIELD) |              // w
   1353     ((uint64_t)1 << UDAT_WEEK_OF_MONTH_FIELD) |             // W
   1354     ((uint64_t)1 << UDAT_HOUR1_FIELD) |                     // h
   1355     ((uint64_t)1 << UDAT_HOUR0_FIELD) |                     // K
   1356     ((uint64_t)1 << UDAT_YEAR_WOY_FIELD) |                  // Y
   1357     ((uint64_t)1 << UDAT_EXTENDED_YEAR_FIELD) |             // u
   1358     ((uint64_t)1 << UDAT_JULIAN_DAY_FIELD) |                // g
   1359     ((uint64_t)1 << UDAT_MILLISECONDS_IN_DAY_FIELD) |       // A
   1360     ((uint64_t)1 << UDAT_RELATED_YEAR_FIELD);               // r
   1361 
   1362 static const uint64_t kNumericFieldsForCount12 =
   1363     ((uint64_t)1 << UDAT_MONTH_FIELD) |                     // M or MM
   1364     ((uint64_t)1 << UDAT_DOW_LOCAL_FIELD) |                 // e or ee
   1365     ((uint64_t)1 << UDAT_STANDALONE_DAY_FIELD) |            // c or cc
   1366     ((uint64_t)1 << UDAT_STANDALONE_MONTH_FIELD) |          // L or LL
   1367     ((uint64_t)1 << UDAT_QUARTER_FIELD) |                   // Q or QQ
   1368     ((uint64_t)1 << UDAT_STANDALONE_QUARTER_FIELD);         // q or qq
   1369 
   1370 UBool U_EXPORT2
   1371 DateFormatSymbols::isNumericField(UDateFormatField f, int32_t count) {
   1372     if (f == UDAT_FIELD_COUNT) {
   1373         return FALSE;
   1374     }
   1375     uint64_t flag = ((uint64_t)1 << f);
   1376     return ((kNumericFieldsAlways & flag) != 0 || ((kNumericFieldsForCount12 & flag) != 0 && count < 3));
   1377 }
   1378 
   1379 UBool U_EXPORT2
   1380 DateFormatSymbols::isNumericPatternChar(UChar c, int32_t count) {
   1381     return isNumericField(getPatternCharIndex(c), count);
   1382 }
   1383 
   1384 //------------------------------------------------------
   1385 
   1386 UnicodeString&
   1387 DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
   1388 {
   1389     // fastCopyFrom() - see assignArray comments
   1390     return result.fastCopyFrom(fLocalPatternChars);
   1391 }
   1392 
   1393 //------------------------------------------------------
   1394 
   1395 void
   1396 DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
   1397 {
   1398     fLocalPatternChars = newLocalPatternChars;
   1399 }
   1400 
   1401 //------------------------------------------------------
   1402 
   1403 static void
   1404 initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) {
   1405     if (U_SUCCESS(status)) {
   1406         int32_t strLen = 0;
   1407         length = ures_getSize(data);
   1408         *field = newUnicodeStringArray(length);
   1409         if (*field) {
   1410             for(int32_t i = 0; i<length; i++) {
   1411                 const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status);
   1412                 // setTo() - see assignArray comments
   1413                 (*(field)+i)->setTo(TRUE, resStr, strLen);
   1414             }
   1415         }
   1416         else {
   1417             length = 0;
   1418             status = U_MEMORY_ALLOCATION_ERROR;
   1419         }
   1420     }
   1421 }
   1422 
   1423 static void
   1424 initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) {
   1425     if (U_SUCCESS(status)) {
   1426         length = numStr;
   1427         *field = newUnicodeStringArray((size_t)numStr);
   1428         if (*field) {
   1429             for(int32_t i = 0; i<length; i++) {
   1430                 // readonly aliases - all "data" strings are constant
   1431                 // -1 as length for variable-length strings (gLastResortDayNames[0] is empty)
   1432                 (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1);
   1433             }
   1434         }
   1435         else {
   1436             length = 0;
   1437             status = U_MEMORY_ALLOCATION_ERROR;
   1438         }
   1439     }
   1440 }
   1441 
   1442 static void
   1443 initLeapMonthPattern(UnicodeString *field, int32_t index, const UResourceBundle *data, UErrorCode &status) {
   1444     field[index].remove();
   1445     if (U_SUCCESS(status)) {
   1446         int32_t strLen = 0;
   1447         const UChar *resStr = ures_getStringByKey(data, gNamesLeapTag, &strLen, &status);
   1448         if (U_SUCCESS(status)) {
   1449             field[index].setTo(TRUE, resStr, strLen);
   1450         }
   1451     }
   1452     status = U_ZERO_ERROR;
   1453 }
   1454 
   1455 typedef struct {
   1456     const char * usageTypeName;
   1457     DateFormatSymbols::ECapitalizationContextUsageType usageTypeEnumValue;
   1458 } ContextUsageTypeNameToEnumValue;
   1459 
   1460 static const ContextUsageTypeNameToEnumValue contextUsageTypeMap[] = {
   1461    // Entries must be sorted by usageTypeName; entry with NULL name terminates list.
   1462     { "day-format-except-narrow", DateFormatSymbols::kCapContextUsageDayFormat },
   1463     { "day-narrow",     DateFormatSymbols::kCapContextUsageDayNarrow },
   1464     { "day-standalone-except-narrow", DateFormatSymbols::kCapContextUsageDayStandalone },
   1465     { "era-abbr",       DateFormatSymbols::kCapContextUsageEraAbbrev },
   1466     { "era-name",       DateFormatSymbols::kCapContextUsageEraWide },
   1467     { "era-narrow",     DateFormatSymbols::kCapContextUsageEraNarrow },
   1468     { "metazone-long",  DateFormatSymbols::kCapContextUsageMetazoneLong },
   1469     { "metazone-short", DateFormatSymbols::kCapContextUsageMetazoneShort },
   1470     { "month-format-except-narrow", DateFormatSymbols::kCapContextUsageMonthFormat },
   1471     { "month-narrow",   DateFormatSymbols::kCapContextUsageMonthNarrow },
   1472     { "month-standalone-except-narrow", DateFormatSymbols::kCapContextUsageMonthStandalone },
   1473     { "zone-long",      DateFormatSymbols::kCapContextUsageZoneLong },
   1474     { "zone-short",     DateFormatSymbols::kCapContextUsageZoneShort },
   1475     { NULL, (DateFormatSymbols::ECapitalizationContextUsageType)0 },
   1476 };
   1477 
   1478 void
   1479 DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData)
   1480 {
   1481     int32_t i;
   1482     int32_t len = 0;
   1483     const UChar *resStr;
   1484     /* In case something goes wrong, initialize all of the data to NULL. */
   1485     fEras = NULL;
   1486     fErasCount = 0;
   1487     fEraNames = NULL;
   1488     fEraNamesCount = 0;
   1489     fNarrowEras = NULL;
   1490     fNarrowErasCount = 0;
   1491     fMonths = NULL;
   1492     fMonthsCount=0;
   1493     fShortMonths = NULL;
   1494     fShortMonthsCount=0;
   1495     fNarrowMonths = NULL;
   1496     fNarrowMonthsCount=0;
   1497     fStandaloneMonths = NULL;
   1498     fStandaloneMonthsCount=0;
   1499     fStandaloneShortMonths = NULL;
   1500     fStandaloneShortMonthsCount=0;
   1501     fStandaloneNarrowMonths = NULL;
   1502     fStandaloneNarrowMonthsCount=0;
   1503     fWeekdays = NULL;
   1504     fWeekdaysCount=0;
   1505     fShortWeekdays = NULL;
   1506     fShortWeekdaysCount=0;
   1507     fShorterWeekdays = NULL;
   1508     fShorterWeekdaysCount=0;
   1509     fNarrowWeekdays = NULL;
   1510     fNarrowWeekdaysCount=0;
   1511     fStandaloneWeekdays = NULL;
   1512     fStandaloneWeekdaysCount=0;
   1513     fStandaloneShortWeekdays = NULL;
   1514     fStandaloneShortWeekdaysCount=0;
   1515     fStandaloneShorterWeekdays = NULL;
   1516     fStandaloneShorterWeekdaysCount=0;
   1517     fStandaloneNarrowWeekdays = NULL;
   1518     fStandaloneNarrowWeekdaysCount=0;
   1519     fAmPms = NULL;
   1520     fAmPmsCount=0;
   1521     fNarrowAmPms = NULL;
   1522     fNarrowAmPmsCount=0;
   1523     fTimeSeparator.setToBogus();
   1524     fQuarters = NULL;
   1525     fQuartersCount = 0;
   1526     fShortQuarters = NULL;
   1527     fShortQuartersCount = 0;
   1528     fStandaloneQuarters = NULL;
   1529     fStandaloneQuartersCount = 0;
   1530     fStandaloneShortQuarters = NULL;
   1531     fStandaloneShortQuartersCount = 0;
   1532     fLeapMonthPatterns = NULL;
   1533     fLeapMonthPatternsCount = 0;
   1534     fShortYearNames = NULL;
   1535     fShortYearNamesCount = 0;
   1536     fShortZodiacNames = NULL;
   1537     fShortZodiacNamesCount = 0;
   1538     fZoneStringsRowCount = 0;
   1539     fZoneStringsColCount = 0;
   1540     fZoneStrings = NULL;
   1541     fLocaleZoneStrings = NULL;
   1542     uprv_memset(fCapitalization, 0, sizeof(fCapitalization));
   1543 
   1544     // We need to preserve the requested locale for
   1545     // lazy ZoneStringFormat instantiation.  ZoneStringFormat
   1546     // is region sensitive, thus, bundle locale bundle's locale
   1547     // is not sufficient.
   1548     fZSFLocale = locale;
   1549 
   1550     if (U_FAILURE(status)) return;
   1551 
   1552     /**
   1553      * Retrieve the string arrays we need from the resource bundle file.
   1554      * We cast away const here, but that's okay; we won't delete any of
   1555      * these.
   1556      */
   1557     CalendarData calData(locale, type, status);
   1558 
   1559     // load the first data item
   1560     UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
   1561     UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
   1562     UErrorCode oldStatus = status;
   1563     UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status);
   1564     if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3
   1565        status = oldStatus;
   1566        eraNames = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
   1567     }
   1568     // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too
   1569     oldStatus = status;
   1570     UResourceBundle *narrowEras = ures_getByKeyWithFallback(erasMain, gNamesNarrowTag, NULL, &status);
   1571     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1572        status = oldStatus;
   1573        narrowEras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
   1574     }
   1575 
   1576     UErrorCode tempStatus = U_ZERO_ERROR;
   1577     UResourceBundle *monthPatterns = calData.getByKey(gMonthPatternsTag, tempStatus);
   1578     if (U_SUCCESS(tempStatus) && monthPatterns != NULL) {
   1579         fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount);
   1580         if (fLeapMonthPatterns) {
   1581             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calData.getByKey2(gMonthPatternsTag, gNamesWideTag, tempStatus), tempStatus);
   1582             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calData.getByKey2(gMonthPatternsTag, gNamesAbbrTag, tempStatus), tempStatus);
   1583             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calData.getByKey2(gMonthPatternsTag, gNamesNarrowTag, tempStatus), tempStatus);
   1584             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus);
   1585             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus);
   1586             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus);
   1587             initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calData.getByKey3(gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus);
   1588             if (U_SUCCESS(tempStatus)) {
   1589                 // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't.
   1590                 // The ordering of the following statements is important.
   1591                 if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) {
   1592                     fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
   1593                 };
   1594                 if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) {
   1595                     fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]);
   1596                 };
   1597                 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) {
   1598                     fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
   1599                 };
   1600                 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) {
   1601                     fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]);
   1602                 };
   1603                 // end of hack
   1604                 fLeapMonthPatternsCount = kMonthPatternsCount;
   1605             } else {
   1606                 delete[] fLeapMonthPatterns;
   1607                 fLeapMonthPatterns = NULL;
   1608             }
   1609         }
   1610     }
   1611 
   1612     tempStatus = U_ZERO_ERROR;
   1613     UResourceBundle *cyclicNameSets= calData.getByKey(gCyclicNameSetsTag, tempStatus);
   1614     if (U_SUCCESS(tempStatus) && cyclicNameSets != NULL) {
   1615         UResourceBundle *nameSetYears = ures_getByKeyWithFallback(cyclicNameSets, gNameSetYearsTag, NULL, &tempStatus);
   1616         if (U_SUCCESS(tempStatus)) {
   1617             UResourceBundle *nameSetYearsFmt = ures_getByKeyWithFallback(nameSetYears, gNamesFormatTag, NULL, &tempStatus);
   1618             if (U_SUCCESS(tempStatus)) {
   1619                 UResourceBundle *nameSetYearsFmtAbbrev = ures_getByKeyWithFallback(nameSetYearsFmt, gNamesAbbrTag, NULL, &tempStatus);
   1620                 if (U_SUCCESS(tempStatus)) {
   1621                     initField(&fShortYearNames, fShortYearNamesCount, nameSetYearsFmtAbbrev, tempStatus);
   1622                     ures_close(nameSetYearsFmtAbbrev);
   1623                 }
   1624                 ures_close(nameSetYearsFmt);
   1625             }
   1626             ures_close(nameSetYears);
   1627         }
   1628         UResourceBundle *nameSetZodiacs = ures_getByKeyWithFallback(cyclicNameSets, gNameSetZodiacsTag, NULL, &tempStatus);
   1629         if (U_SUCCESS(tempStatus)) {
   1630             UResourceBundle *nameSetZodiacsFmt = ures_getByKeyWithFallback(nameSetZodiacs, gNamesFormatTag, NULL, &tempStatus);
   1631             if (U_SUCCESS(tempStatus)) {
   1632                 UResourceBundle *nameSetZodiacsFmtAbbrev = ures_getByKeyWithFallback(nameSetZodiacsFmt, gNamesAbbrTag, NULL, &tempStatus);
   1633                 if (U_SUCCESS(tempStatus)) {
   1634                     initField(&fShortZodiacNames, fShortZodiacNamesCount, nameSetZodiacsFmtAbbrev, tempStatus);
   1635                     ures_close(nameSetZodiacsFmtAbbrev);
   1636                 }
   1637                 ures_close(nameSetZodiacsFmt);
   1638             }
   1639             ures_close(nameSetZodiacs);
   1640         }
   1641     }
   1642 
   1643     tempStatus = U_ZERO_ERROR;
   1644     UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus);
   1645     if (U_SUCCESS(tempStatus)) {
   1646         UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, gContextTransformsTag, NULL, &tempStatus);
   1647         if (U_SUCCESS(tempStatus)) {
   1648             UResourceBundle *contextTransformUsage;
   1649             while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &tempStatus)) != NULL ) {
   1650                 const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);
   1651                 if (U_SUCCESS(tempStatus) && intVector != NULL && len >= 2) {
   1652                     const char* usageType = ures_getKey(contextTransformUsage);
   1653                     if (usageType != NULL) {
   1654                         const ContextUsageTypeNameToEnumValue * typeMapPtr = contextUsageTypeMap;
   1655                         int32_t compResult = 0;
   1656                         // linear search; list is short and we cannot be sure that bsearch is available
   1657                         while ( typeMapPtr->usageTypeName != NULL && (compResult = uprv_strcmp(usageType, typeMapPtr->usageTypeName)) > 0 ) {
   1658                             ++typeMapPtr;
   1659                         }
   1660                         if (typeMapPtr->usageTypeName != NULL && compResult == 0) {
   1661                             fCapitalization[typeMapPtr->usageTypeEnumValue][0] = intVector[0];
   1662                             fCapitalization[typeMapPtr->usageTypeEnumValue][1] = intVector[1];
   1663                         }
   1664                     }
   1665                 }
   1666                 tempStatus = U_ZERO_ERROR;
   1667                 ures_close(contextTransformUsage);
   1668             }
   1669             ures_close(contextTransforms);
   1670         }
   1671 
   1672         tempStatus = U_ZERO_ERROR;
   1673         const LocalPointer<NumberingSystem> numberingSystem(
   1674                 NumberingSystem::createInstance(locale, tempStatus), tempStatus);
   1675         if (U_SUCCESS(tempStatus)) {
   1676             // These functions all fail gracefully if passed NULL pointers and
   1677             // do nothing unless U_SUCCESS(tempStatus), so it's only necessary
   1678             // to check for errors once after all calls are made.
   1679             const LocalUResourceBundlePointer numberElementsData(ures_getByKeyWithFallback(
   1680                     localeBundle, gNumberElementsTag, NULL, &tempStatus));
   1681             const LocalUResourceBundlePointer nsNameData(ures_getByKeyWithFallback(
   1682                     numberElementsData.getAlias(), numberingSystem->getName(), NULL, &tempStatus));
   1683             const LocalUResourceBundlePointer symbolsData(ures_getByKeyWithFallback(
   1684                     nsNameData.getAlias(), gSymbolsTag, NULL, &tempStatus));
   1685             fTimeSeparator = ures_getUnicodeStringByKey(
   1686                     symbolsData.getAlias(), gTimeSeparatorTag, &tempStatus);
   1687             if (U_FAILURE(tempStatus)) {
   1688                 fTimeSeparator.setToBogus();
   1689             }
   1690         }
   1691 
   1692         ures_close(localeBundle);
   1693     }
   1694 
   1695     if (fTimeSeparator.isBogus()) {
   1696         fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR);
   1697     }
   1698 
   1699     UResourceBundle *weekdaysData = NULL; // Data closed by calData
   1700     UResourceBundle *abbrWeekdaysData = NULL; // Data closed by calData
   1701     UResourceBundle *shorterWeekdaysData = NULL; // Data closed by calData
   1702     UResourceBundle *narrowWeekdaysData = NULL; // Data closed by calData
   1703     UResourceBundle *standaloneWeekdaysData = NULL; // Data closed by calData
   1704     UResourceBundle *standaloneAbbrWeekdaysData = NULL; // Data closed by calData
   1705     UResourceBundle *standaloneShorterWeekdaysData = NULL; // Data closed by calData
   1706     UResourceBundle *standaloneNarrowWeekdaysData = NULL; // Data closed by calData
   1707 
   1708     U_LOCALE_BASED(locBased, *this);
   1709     if (U_FAILURE(status))
   1710     {
   1711         if (useLastResortData)
   1712         {
   1713             // Handle the case in which there is no resource data present.
   1714             // We don't have to generate usable patterns in this situation;
   1715             // we just need to produce something that will be semi-intelligible
   1716             // in most locales.
   1717 
   1718             status = U_USING_FALLBACK_WARNING;
   1719 
   1720             initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
   1721             initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
   1722             initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
   1723             initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
   1724             initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
   1725             initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
   1726             initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
   1727             initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
   1728             initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
   1729             initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1730             initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1731             initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1732             initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1733             initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1734             initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1735             initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1736             initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
   1737             initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
   1738             initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
   1739             initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
   1740             initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
   1741             initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
   1742             initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
   1743             fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
   1744         }
   1745         goto cleanup;
   1746     }
   1747 
   1748     // if we make it to here, the resource data is cool, and we can get everything out
   1749     // of it that we need except for the time-zone and localized-pattern data, which
   1750     // are stored in a separate file
   1751     locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status),
   1752                           ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status));
   1753 
   1754     initField(&fEras, fErasCount, eras, status);
   1755     initField(&fEraNames, fEraNamesCount, eraNames, status);
   1756     initField(&fNarrowEras, fNarrowErasCount, narrowEras, status);
   1757 
   1758     initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
   1759     initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
   1760 
   1761     initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
   1762     if(status == U_MISSING_RESOURCE_ERROR) {
   1763         status = U_ZERO_ERROR;
   1764         initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
   1765     }
   1766     if ( status == U_MISSING_RESOURCE_ERROR ) { /* If format/narrow not available, use format/abbreviated */
   1767        status = U_ZERO_ERROR;
   1768        initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
   1769     }
   1770 
   1771     initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status);
   1772     if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/wide not available, use format/wide */
   1773        status = U_ZERO_ERROR;
   1774        initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
   1775     }
   1776     initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
   1777     if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/abbreviated not available, use format/abbreviated */
   1778        status = U_ZERO_ERROR;
   1779        initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
   1780     }
   1781     initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
   1782     if ( status == U_MISSING_RESOURCE_ERROR ) { /* if standalone/narrow not availabe, try format/narrow */
   1783        status = U_ZERO_ERROR;
   1784        initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
   1785        if ( status == U_MISSING_RESOURCE_ERROR ) { /* if still not there, use format/abbreviated */
   1786           status = U_ZERO_ERROR;
   1787           initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
   1788        }
   1789     }
   1790     initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);
   1791     initField(&fNarrowAmPms, fNarrowAmPmsCount, calData.getByKey(gAmPmMarkersNarrowTag, status), status);
   1792 
   1793     initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
   1794     initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
   1795 
   1796     initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status);
   1797     if(status == U_MISSING_RESOURCE_ERROR) {
   1798         status = U_ZERO_ERROR;
   1799         initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
   1800     }
   1801 
   1802     initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
   1803     if(status == U_MISSING_RESOURCE_ERROR) {
   1804         status = U_ZERO_ERROR;
   1805         initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
   1806     }
   1807 
   1808     // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597)
   1809     /*
   1810     // fastCopyFrom()/setTo() - see assignArray comments
   1811     resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status);
   1812     fLocalPatternChars.setTo(TRUE, resStr, len);
   1813     // If the locale data does not include new pattern chars, use the defaults
   1814     // TODO: Consider making this an error, since this may add conflicting characters.
   1815     if (len < PATTERN_CHARS_LEN) {
   1816         fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
   1817     }
   1818     */
   1819     fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
   1820 
   1821     // Format wide weekdays -> fWeekdays
   1822     // {sfb} fixed to handle 1-based weekdays
   1823     weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
   1824     fWeekdaysCount = ures_getSize(weekdaysData);
   1825     fWeekdays = new UnicodeString[fWeekdaysCount+1];
   1826     /* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/
   1827     if (fWeekdays == NULL) {
   1828         status = U_MEMORY_ALLOCATION_ERROR;
   1829         goto cleanup;
   1830     }
   1831     // leave fWeekdays[0] empty
   1832     for(i = 0; i<fWeekdaysCount; i++) {
   1833         resStr = ures_getStringByIndex(weekdaysData, i, &len, &status);
   1834         // setTo() - see assignArray comments
   1835         fWeekdays[i+1].setTo(TRUE, resStr, len);
   1836     }
   1837     fWeekdaysCount++;
   1838 
   1839     // Format abbreviated weekdays -> fShortWeekdays
   1840     abbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1841     fShortWeekdaysCount = ures_getSize(abbrWeekdaysData);
   1842     fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1];
   1843     /* test for NULL */
   1844     if (fShortWeekdays == 0) {
   1845         status = U_MEMORY_ALLOCATION_ERROR;
   1846         goto cleanup;
   1847     }
   1848     // leave fShortWeekdays[0] empty
   1849     for(i = 0; i<fShortWeekdaysCount; i++) {
   1850         resStr = ures_getStringByIndex(abbrWeekdaysData, i, &len, &status);
   1851         // setTo() - see assignArray comments
   1852         fShortWeekdays[i+1].setTo(TRUE, resStr, len);
   1853     }
   1854     fShortWeekdaysCount++;
   1855 
   1856    // Format short weekdays -> fShorterWeekdays (fall back to abbreviated)
   1857     shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesShortTag, status);
   1858     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1859        status = U_ZERO_ERROR;
   1860        shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1861     }
   1862     fShorterWeekdaysCount = ures_getSize(shorterWeekdaysData);
   1863     fShorterWeekdays = new UnicodeString[fShorterWeekdaysCount+1];
   1864     /* test for NULL */
   1865     if (fShorterWeekdays == 0) {
   1866         status = U_MEMORY_ALLOCATION_ERROR;
   1867         goto cleanup;
   1868     }
   1869     // leave fShorterWeekdays[0] empty
   1870     for(i = 0; i<fShorterWeekdaysCount; i++) {
   1871         resStr = ures_getStringByIndex(shorterWeekdaysData, i, &len, &status);
   1872         // setTo() - see assignArray comments
   1873         fShorterWeekdays[i+1].setTo(TRUE, resStr, len);
   1874     }
   1875     fShorterWeekdaysCount++;
   1876 
   1877    // Format narrow weekdays -> fNarrowWeekdays
   1878     narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
   1879     if(status == U_MISSING_RESOURCE_ERROR) {
   1880         status = U_ZERO_ERROR;
   1881         narrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
   1882     }
   1883     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1884        status = U_ZERO_ERROR;
   1885        narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1886     }
   1887     fNarrowWeekdaysCount = ures_getSize(narrowWeekdaysData);
   1888     fNarrowWeekdays = new UnicodeString[fNarrowWeekdaysCount+1];
   1889     /* test for NULL */
   1890     if (fNarrowWeekdays == 0) {
   1891         status = U_MEMORY_ALLOCATION_ERROR;
   1892         goto cleanup;
   1893     }
   1894     // leave fNarrowWeekdays[0] empty
   1895     for(i = 0; i<fNarrowWeekdaysCount; i++) {
   1896         resStr = ures_getStringByIndex(narrowWeekdaysData, i, &len, &status);
   1897         // setTo() - see assignArray comments
   1898         fNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
   1899     }
   1900     fNarrowWeekdaysCount++;
   1901 
   1902    // Stand-alone wide weekdays -> fStandaloneWeekdays
   1903     standaloneWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status);
   1904     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1905        status = U_ZERO_ERROR;
   1906        standaloneWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
   1907     }
   1908     fStandaloneWeekdaysCount = ures_getSize(standaloneWeekdaysData);
   1909     fStandaloneWeekdays = new UnicodeString[fStandaloneWeekdaysCount+1];
   1910     /* test for NULL */
   1911     if (fStandaloneWeekdays == 0) {
   1912         status = U_MEMORY_ALLOCATION_ERROR;
   1913         goto cleanup;
   1914     }
   1915     // leave fStandaloneWeekdays[0] empty
   1916     for(i = 0; i<fStandaloneWeekdaysCount; i++) {
   1917         resStr = ures_getStringByIndex(standaloneWeekdaysData, i, &len, &status);
   1918         // setTo() - see assignArray comments
   1919         fStandaloneWeekdays[i+1].setTo(TRUE, resStr, len);
   1920     }
   1921     fStandaloneWeekdaysCount++;
   1922 
   1923    // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays
   1924     standaloneAbbrWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status);
   1925     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1926        status = U_ZERO_ERROR;
   1927        standaloneAbbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1928     }
   1929     fStandaloneShortWeekdaysCount = ures_getSize(standaloneAbbrWeekdaysData);
   1930     fStandaloneShortWeekdays = new UnicodeString[fStandaloneShortWeekdaysCount+1];
   1931     /* test for NULL */
   1932     if (fStandaloneShortWeekdays == 0) {
   1933         status = U_MEMORY_ALLOCATION_ERROR;
   1934         goto cleanup;
   1935     }
   1936     // leave fStandaloneShortWeekdays[0] empty
   1937     for(i = 0; i<fStandaloneShortWeekdaysCount; i++) {
   1938         resStr = ures_getStringByIndex(standaloneAbbrWeekdaysData, i, &len, &status);
   1939         // setTo() - see assignArray comments
   1940         fStandaloneShortWeekdays[i+1].setTo(TRUE, resStr, len);
   1941     }
   1942     fStandaloneShortWeekdaysCount++;
   1943 
   1944     // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated)
   1945     standaloneShorterWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status);
   1946     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1947        status = U_ZERO_ERROR;
   1948        standaloneShorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1949     }
   1950     fStandaloneShorterWeekdaysCount = ures_getSize(standaloneShorterWeekdaysData);
   1951     fStandaloneShorterWeekdays = new UnicodeString[fStandaloneShorterWeekdaysCount+1];
   1952     /* test for NULL */
   1953     if (fStandaloneShorterWeekdays == 0) {
   1954         status = U_MEMORY_ALLOCATION_ERROR;
   1955         goto cleanup;
   1956     }
   1957     // leave fStandaloneShorterWeekdays[0] empty
   1958     for(i = 0; i<fStandaloneShorterWeekdaysCount; i++) {
   1959         resStr = ures_getStringByIndex(standaloneShorterWeekdaysData, i, &len, &status);
   1960         // setTo() - see assignArray comments
   1961         fStandaloneShorterWeekdays[i+1].setTo(TRUE, resStr, len);
   1962     }
   1963     fStandaloneShorterWeekdaysCount++;
   1964 
   1965     // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays
   1966     standaloneNarrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
   1967     if ( status == U_MISSING_RESOURCE_ERROR ) {
   1968        status = U_ZERO_ERROR;
   1969        standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
   1970        if ( status == U_MISSING_RESOURCE_ERROR ) {
   1971           status = U_ZERO_ERROR;
   1972           standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
   1973        }
   1974     }
   1975     fStandaloneNarrowWeekdaysCount = ures_getSize(standaloneNarrowWeekdaysData);
   1976     fStandaloneNarrowWeekdays = new UnicodeString[fStandaloneNarrowWeekdaysCount+1];
   1977     /* test for NULL */
   1978     if (fStandaloneNarrowWeekdays == 0) {
   1979         status = U_MEMORY_ALLOCATION_ERROR;
   1980         goto cleanup;
   1981     }
   1982     // leave fStandaloneNarrowWeekdays[0] empty
   1983     for(i = 0; i<fStandaloneNarrowWeekdaysCount; i++) {
   1984         resStr = ures_getStringByIndex(standaloneNarrowWeekdaysData, i, &len, &status);
   1985         // setTo() - see assignArray comments
   1986         fStandaloneNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
   1987     }
   1988     fStandaloneNarrowWeekdaysCount++;
   1989 
   1990 cleanup:
   1991     ures_close(eras);
   1992     ures_close(eraNames);
   1993     ures_close(narrowEras);
   1994 }
   1995 
   1996 Locale
   1997 DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
   1998     U_LOCALE_BASED(locBased, *this);
   1999     return locBased.getLocale(type, status);
   2000 }
   2001 
   2002 U_NAMESPACE_END
   2003 
   2004 #endif /* #if !UCONFIG_NO_FORMATTING */
   2005 
   2006 //eof
   2007