intl/icu/source/i18n/dtfmtsym.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial