• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
newUnicodeStringArray(size_t count)203 static inline UnicodeString* newUnicodeStringArray(size_t count) {
204     return new UnicodeString[count ? count : 1];
205 }
206 
207 //------------------------------------------------------
208 
DateFormatSymbols(const Locale & locale,UErrorCode & status)209 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
210                                      UErrorCode& status)
211     : UObject()
212 {
213   initializeData(locale, NULL,  status);
214 }
215 
DateFormatSymbols(UErrorCode & status)216 DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
217     : UObject()
218 {
219   initializeData(Locale::getDefault(), NULL, status, TRUE);
220 }
221 
222 
DateFormatSymbols(const Locale & locale,const char * type,UErrorCode & status)223 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
224                                      const char *type,
225                                      UErrorCode& status)
226     : UObject()
227 {
228   initializeData(locale, type,  status);
229 }
230 
DateFormatSymbols(const char * type,UErrorCode & status)231 DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
232     : UObject()
233 {
234   initializeData(Locale::getDefault(), type, status, TRUE);
235 }
236 
DateFormatSymbols(const DateFormatSymbols & other)237 DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
238     : UObject(other)
239 {
240     copyData(other);
241 }
242 
243 void
assignArray(UnicodeString * & dstArray,int32_t & dstCount,const UnicodeString * srcArray,int32_t srcCount)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
createZoneStrings(const UnicodeString * const * otherStrings)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
copyData(const DateFormatSymbols & other)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  */
operator =(const DateFormatSymbols & other)359 DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
360 {
361     dispose();
362     copyData(other);
363 
364     return *this;
365 }
366 
~DateFormatSymbols()367 DateFormatSymbols::~DateFormatSymbols()
368 {
369     dispose();
370 }
371 
dispose()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 
disposeZoneStrings()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
arrayCompare(const UnicodeString * array1,const UnicodeString * array2,int32_t count)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
operator ==(const DateFormatSymbols & other) const445 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*
getEras(int32_t & count) const521 DateFormatSymbols::getEras(int32_t &count) const
522 {
523     count = fErasCount;
524     return fEras;
525 }
526 
527 const UnicodeString*
getEraNames(int32_t & count) const528 DateFormatSymbols::getEraNames(int32_t &count) const
529 {
530     count = fEraNamesCount;
531     return fEraNames;
532 }
533 
534 const UnicodeString*
getNarrowEras(int32_t & count) const535 DateFormatSymbols::getNarrowEras(int32_t &count) const
536 {
537     count = fNarrowErasCount;
538     return fNarrowEras;
539 }
540 
541 const UnicodeString*
getMonths(int32_t & count) const542 DateFormatSymbols::getMonths(int32_t &count) const
543 {
544     count = fMonthsCount;
545     return fMonths;
546 }
547 
548 const UnicodeString*
getShortMonths(int32_t & count) const549 DateFormatSymbols::getShortMonths(int32_t &count) const
550 {
551     count = fShortMonthsCount;
552     return fShortMonths;
553 }
554 
555 const UnicodeString*
getMonths(int32_t & count,DtContextType context,DtWidthType width) const556 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*
getWeekdays(int32_t & count) const604 DateFormatSymbols::getWeekdays(int32_t &count) const
605 {
606     count = fWeekdaysCount;
607     return fWeekdays;
608 }
609 
610 const UnicodeString*
getShortWeekdays(int32_t & count) const611 DateFormatSymbols::getShortWeekdays(int32_t &count) const
612 {
613     count = fShortWeekdaysCount;
614     return fShortWeekdays;
615 }
616 
617 const UnicodeString*
getWeekdays(int32_t & count,DtContextType context,DtWidthType width) const618 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*
getQuarters(int32_t & count,DtContextType context,DtWidthType width) const665 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*
getAmPmStrings(int32_t & count) const713 DateFormatSymbols::getAmPmStrings(int32_t &count) const
714 {
715     count = fAmPmsCount;
716     return fAmPms;
717 }
718 
719 //------------------------------------------------------
720 
721 void
setEras(const UnicodeString * erasArray,int32_t count)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
setEraNames(const UnicodeString * eraNamesArray,int32_t count)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
setNarrowEras(const UnicodeString * narrowErasArray,int32_t count)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
setMonths(const UnicodeString * monthsArray,int32_t count)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
setShortMonths(const UnicodeString * shortMonthsArray,int32_t count)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
setMonths(const UnicodeString * monthsArray,int32_t count,DtContextType context,DtWidthType width)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 
setWeekdays(const UnicodeString * weekdaysArray,int32_t count)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
setShortWeekdays(const UnicodeString * shortWeekdaysArray,int32_t count)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
setWeekdays(const UnicodeString * weekdaysArray,int32_t count,DtContextType context,DtWidthType width)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
setQuarters(const UnicodeString * quartersArray,int32_t count,DtContextType context,DtWidthType width)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
setAmPmStrings(const UnicodeString * amPmsArray,int32_t count)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*
getZoneStringFormat(void) const1038 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
initZoneStringFormat(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**
getZoneStrings(int32_t & rowCount,int32_t & columnCount) const1072 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
initZoneStringsArray(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
setZoneStrings(const UnicodeString * const * strings,int32_t rowCount,int32_t columnCount)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
getPatternUChars(void)1122 DateFormatSymbols::getPatternUChars(void)
1123 {
1124     return gPatternChars;
1125 }
1126 
1127 //------------------------------------------------------
1128 
1129 UnicodeString&
getLocalPatternChars(UnicodeString & result) const1130 DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
1131 {
1132     // fastCopyFrom() - see assignArray comments
1133     return result.fastCopyFrom(fLocalPatternChars);
1134 }
1135 
1136 //------------------------------------------------------
1137 
1138 void
setLocalPatternChars(const UnicodeString & newLocalPatternChars)1139 DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
1140 {
1141     fLocalPatternChars = newLocalPatternChars;
1142 }
1143 
1144 //------------------------------------------------------
1145 
1146 static void
initField(UnicodeString ** field,int32_t & length,const UResourceBundle * data,UErrorCode & status)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
initField(UnicodeString ** field,int32_t & length,const UChar * data,LastResortSize numStr,LastResortSize strLen,UErrorCode & status)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
initializeData(const Locale & locale,const char * type,UErrorCode & status,UBool useLastResortData)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
getLocale(ULocDataLocaleType type,UErrorCode & status) const1567 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