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