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