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