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