/src/icu/source/i18n/dtfmtsym.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | // © 2016 and later: Unicode, Inc. and others.  | 
2  |  | // License & terms of use: http://www.unicode.org/copyright.html  | 
3  |  | /*  | 
4  |  | *******************************************************************************  | 
5  |  | * Copyright (C) 1997-2016, International Business Machines Corporation and    *  | 
6  |  | * others. All Rights Reserved.                                                *  | 
7  |  | *******************************************************************************  | 
8  |  | *  | 
9  |  | * File DTFMTSYM.CPP  | 
10  |  | *  | 
11  |  | * Modification History:  | 
12  |  | *  | 
13  |  | *   Date        Name        Description  | 
14  |  | *   02/19/97    aliu        Converted from java.  | 
15  |  | *   07/21/98    stephen     Added getZoneIndex  | 
16  |  | *                            Changed weekdays/short weekdays to be one-based  | 
17  |  | *   06/14/99    stephen     Removed SimpleDateFormat::fgTimeZoneDataSuffix  | 
18  |  | *   11/16/99    weiv        Added 'Y' and 'e' to fgPatternChars  | 
19  |  | *   03/27/00    weiv        Keeping resource bundle around!  | 
20  |  | *   06/30/05    emmons      Added eraNames, narrow month/day, standalone context  | 
21  |  | *   10/12/05    emmons      Added setters for eraNames, month/day by width/context  | 
22  |  | *******************************************************************************  | 
23  |  | */  | 
24  |  |  | 
25  |  | #include <utility>  | 
26  |  |  | 
27  |  | #include "unicode/utypes.h"  | 
28  |  |  | 
29  |  | #if !UCONFIG_NO_FORMATTING  | 
30  |  | #include "unicode/ustring.h"  | 
31  |  | #include "unicode/localpointer.h"  | 
32  |  | #include "unicode/dtfmtsym.h"  | 
33  |  | #include "unicode/smpdtfmt.h"  | 
34  |  | #include "unicode/msgfmt.h"  | 
35  |  | #include "unicode/numsys.h"  | 
36  |  | #include "unicode/tznames.h"  | 
37  |  | #include "cpputils.h"  | 
38  |  | #include "umutex.h"  | 
39  |  | #include "cmemory.h"  | 
40  |  | #include "cstring.h"  | 
41  |  | #include "charstr.h"  | 
42  |  | #include "dt_impl.h"  | 
43  |  | #include "locbased.h"  | 
44  |  | #include "gregoimp.h"  | 
45  |  | #include "hash.h"  | 
46  |  | #include "uassert.h"  | 
47  |  | #include "uresimp.h"  | 
48  |  | #include "ureslocs.h"  | 
49  |  | #include "uvector.h"  | 
50  |  | #include "shareddateformatsymbols.h"  | 
51  |  | #include "unicode/calendar.h"  | 
52  |  | #include "unifiedcache.h"  | 
53  |  |  | 
54  |  | // *****************************************************************************  | 
55  |  | // class DateFormatSymbols  | 
56  |  | // *****************************************************************************  | 
57  |  |  | 
58  |  | /**  | 
59  |  |  * These are static arrays we use only in the case where we have no  | 
60  |  |  * resource data.  | 
61  |  |  */  | 
62  |  |  | 
63  |  | #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR  | 
64  |  | #define PATTERN_CHARS_LEN 38  | 
65  |  | #else  | 
66  | 0  | #define PATTERN_CHARS_LEN 37  | 
67  |  | #endif  | 
68  |  |  | 
69  |  | /**  | 
70  |  |  * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All  | 
71  |  |  * locales use the same these unlocalized pattern characters.  | 
72  |  |  */  | 
73  |  | static const UChar gPatternChars[] = { | 
74  |  |     // if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR:  | 
75  |  |     //   GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:  | 
76  |  |     // else:  | 
77  |  |     //   GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB  | 
78  |  |  | 
79  |  |     0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,  | 
80  |  |     0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,  | 
81  |  |     0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0x56,  | 
82  |  |     0x55, 0x4F, 0x58, 0x78, 0x72, 0x62, 0x42,  | 
83  |  | #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR  | 
84  |  |     0x3a,  | 
85  |  | #endif  | 
86  |  |     0  | 
87  |  | };  | 
88  |  |  | 
89  |  | //------------------------------------------------------  | 
90  |  | // Strings of last resort.  These are only used if we have no resource  | 
91  |  | // files.  They aren't designed for actual use, just for backup.  | 
92  |  |  | 
93  |  | // These are the month names and abbreviations of last resort.  | 
94  |  | static const UChar gLastResortMonthNames[13][3] =  | 
95  |  | { | 
96  |  |     {0x0030, 0x0031, 0x0000}, /* "01" */ | 
97  |  |     {0x0030, 0x0032, 0x0000}, /* "02" */ | 
98  |  |     {0x0030, 0x0033, 0x0000}, /* "03" */ | 
99  |  |     {0x0030, 0x0034, 0x0000}, /* "04" */ | 
100  |  |     {0x0030, 0x0035, 0x0000}, /* "05" */ | 
101  |  |     {0x0030, 0x0036, 0x0000}, /* "06" */ | 
102  |  |     {0x0030, 0x0037, 0x0000}, /* "07" */ | 
103  |  |     {0x0030, 0x0038, 0x0000}, /* "08" */ | 
104  |  |     {0x0030, 0x0039, 0x0000}, /* "09" */ | 
105  |  |     {0x0031, 0x0030, 0x0000}, /* "10" */ | 
106  |  |     {0x0031, 0x0031, 0x0000}, /* "11" */ | 
107  |  |     {0x0031, 0x0032, 0x0000}, /* "12" */ | 
108  |  |     {0x0031, 0x0033, 0x0000}  /* "13" */ | 
109  |  | };  | 
110  |  |  | 
111  |  | // These are the weekday names and abbreviations of last resort.  | 
112  |  | static const UChar gLastResortDayNames[8][2] =  | 
113  |  | { | 
114  |  |     {0x0030, 0x0000}, /* "0" */ | 
115  |  |     {0x0031, 0x0000}, /* "1" */ | 
116  |  |     {0x0032, 0x0000}, /* "2" */ | 
117  |  |     {0x0033, 0x0000}, /* "3" */ | 
118  |  |     {0x0034, 0x0000}, /* "4" */ | 
119  |  |     {0x0035, 0x0000}, /* "5" */ | 
120  |  |     {0x0036, 0x0000}, /* "6" */ | 
121  |  |     {0x0037, 0x0000}  /* "7" */ | 
122  |  | };  | 
123  |  |  | 
124  |  | // These are the quarter names and abbreviations of last resort.  | 
125  |  | static const UChar gLastResortQuarters[4][2] =  | 
126  |  | { | 
127  |  |     {0x0031, 0x0000}, /* "1" */ | 
128  |  |     {0x0032, 0x0000}, /* "2" */ | 
129  |  |     {0x0033, 0x0000}, /* "3" */ | 
130  |  |     {0x0034, 0x0000}, /* "4" */ | 
131  |  | };  | 
132  |  |  | 
133  |  | // These are the am/pm and BC/AD markers of last resort.  | 
134  |  | static const UChar gLastResortAmPmMarkers[2][3] =  | 
135  |  | { | 
136  |  |     {0x0041, 0x004D, 0x0000}, /* "AM" */ | 
137  |  |     {0x0050, 0x004D, 0x0000}  /* "PM" */ | 
138  |  | };  | 
139  |  |  | 
140  |  | static const UChar gLastResortEras[2][3] =  | 
141  |  | { | 
142  |  |     {0x0042, 0x0043, 0x0000}, /* "BC" */ | 
143  |  |     {0x0041, 0x0044, 0x0000}  /* "AD" */ | 
144  |  | };  | 
145  |  |  | 
146  |  | /* Sizes for the last resort string arrays */  | 
147  |  | typedef enum LastResortSize { | 
148  |  |     kMonthNum = 13,  | 
149  |  |     kMonthLen = 3,  | 
150  |  |  | 
151  |  |     kDayNum = 8,  | 
152  |  |     kDayLen = 2,  | 
153  |  |  | 
154  |  |     kAmPmNum = 2,  | 
155  |  |     kAmPmLen = 3,  | 
156  |  |  | 
157  |  |     kQuarterNum = 4,  | 
158  |  |     kQuarterLen = 2,  | 
159  |  |  | 
160  |  |     kEraNum = 2,  | 
161  |  |     kEraLen = 3,  | 
162  |  |  | 
163  |  |     kZoneNum = 5,  | 
164  |  |     kZoneLen = 4,  | 
165  |  |  | 
166  |  |     kGmtHourNum = 4,  | 
167  |  |     kGmtHourLen = 10  | 
168  |  | } LastResortSize;  | 
169  |  |  | 
170  |  | U_NAMESPACE_BEGIN  | 
171  |  |  | 
172  | 0  | SharedDateFormatSymbols::~SharedDateFormatSymbols() { | 
173  | 0  | }  | 
174  |  |  | 
175  |  | template<> U_I18N_API  | 
176  |  | const SharedDateFormatSymbols *  | 
177  |  |         LocaleCacheKey<SharedDateFormatSymbols>::createObject(  | 
178  | 0  |                 const void * /*unusedContext*/, UErrorCode &status) const { | 
179  | 0  |     char type[256];  | 
180  | 0  |     Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status);  | 
181  | 0  |     if (U_FAILURE(status)) { | 
182  | 0  |         return NULL;  | 
183  | 0  |     }  | 
184  | 0  |     SharedDateFormatSymbols *shared  | 
185  | 0  |             = new SharedDateFormatSymbols(fLoc, type, status);  | 
186  | 0  |     if (shared == NULL) { | 
187  | 0  |         status = U_MEMORY_ALLOCATION_ERROR;  | 
188  | 0  |         return NULL;  | 
189  | 0  |     }  | 
190  | 0  |     if (U_FAILURE(status)) { | 
191  | 0  |         delete shared;  | 
192  | 0  |         return NULL;  | 
193  | 0  |     }  | 
194  | 0  |     shared->addRef();  | 
195  | 0  |     return shared;  | 
196  | 0  | }  | 
197  |  |  | 
198  |  | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)  | 
199  |  |  | 
200  |  | #define kSUPPLEMENTAL "supplementalData"  | 
201  |  |  | 
202  |  | /**  | 
203  |  |  * These are the tags we expect to see in normal resource bundle files associated  | 
204  |  |  * with a locale and calendar  | 
205  |  |  */  | 
206  |  | static const char gCalendarTag[]="calendar";  | 
207  |  | static const char gGregorianTag[]="gregorian";  | 
208  |  | static const char gErasTag[]="eras";  | 
209  |  | static const char gCyclicNameSetsTag[]="cyclicNameSets";  | 
210  |  | static const char gNameSetYearsTag[]="years";  | 
211  |  | static const char gNameSetZodiacsTag[]="zodiacs";  | 
212  |  | static const char gMonthNamesTag[]="monthNames";  | 
213  |  | static const char gMonthPatternsTag[]="monthPatterns";  | 
214  |  | static const char gDayNamesTag[]="dayNames";  | 
215  |  | static const char gNamesWideTag[]="wide";  | 
216  |  | static const char gNamesAbbrTag[]="abbreviated";  | 
217  |  | static const char gNamesShortTag[]="short";  | 
218  |  | static const char gNamesNarrowTag[]="narrow";  | 
219  |  | static const char gNamesAllTag[]="all";  | 
220  |  | static const char gNamesFormatTag[]="format";  | 
221  |  | static const char gNamesStandaloneTag[]="stand-alone";  | 
222  |  | static const char gNamesNumericTag[]="numeric";  | 
223  |  | static const char gAmPmMarkersTag[]="AmPmMarkers";  | 
224  |  | static const char gAmPmMarkersAbbrTag[]="AmPmMarkersAbbr";  | 
225  |  | static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow";  | 
226  |  | static const char gQuartersTag[]="quarters";  | 
227  |  | static const char gNumberElementsTag[]="NumberElements";  | 
228  |  | static const char gSymbolsTag[]="symbols";  | 
229  |  | static const char gTimeSeparatorTag[]="timeSeparator";  | 
230  |  | static const char gDayPeriodTag[]="dayPeriod";  | 
231  |  |  | 
232  |  | // static const char gZoneStringsTag[]="zoneStrings";  | 
233  |  |  | 
234  |  | // static const char gLocalPatternCharsTag[]="localPatternChars";  | 
235  |  |  | 
236  |  | static const char gContextTransformsTag[]="contextTransforms";  | 
237  |  |  | 
238  |  | /**  | 
239  |  |  * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.  | 
240  |  |  * Work around this.  | 
241  |  |  */  | 
242  | 0  | static inline UnicodeString* newUnicodeStringArray(size_t count) { | 
243  | 0  |     return new UnicodeString[count ? count : 1];  | 
244  | 0  | }  | 
245  |  |  | 
246  |  | //------------------------------------------------------  | 
247  |  |  | 
248  |  | DateFormatSymbols * U_EXPORT2  | 
249  |  | DateFormatSymbols::createForLocale(  | 
250  | 0  |         const Locale& locale, UErrorCode &status) { | 
251  | 0  |     const SharedDateFormatSymbols *shared = NULL;  | 
252  | 0  |     UnifiedCache::getByLocale(locale, shared, status);  | 
253  | 0  |     if (U_FAILURE(status)) { | 
254  | 0  |         return NULL;  | 
255  | 0  |     }  | 
256  | 0  |     DateFormatSymbols *result = new DateFormatSymbols(shared->get());  | 
257  | 0  |     shared->removeRef();  | 
258  | 0  |     if (result == NULL) { | 
259  | 0  |         status = U_MEMORY_ALLOCATION_ERROR;  | 
260  | 0  |         return NULL;  | 
261  | 0  |     }  | 
262  | 0  |     return result;  | 
263  | 0  | }  | 
264  |  |  | 
265  |  | DateFormatSymbols::DateFormatSymbols(const Locale& locale,  | 
266  |  |                                      UErrorCode& status)  | 
267  | 0  |     : UObject()  | 
268  | 0  | { | 
269  | 0  |   initializeData(locale, NULL,  status);  | 
270  | 0  | }  | 
271  |  |  | 
272  |  | DateFormatSymbols::DateFormatSymbols(UErrorCode& status)  | 
273  | 0  |     : UObject()  | 
274  | 0  | { | 
275  | 0  |   initializeData(Locale::getDefault(), NULL, status, TRUE);  | 
276  | 0  | }  | 
277  |  |  | 
278  |  |  | 
279  |  | DateFormatSymbols::DateFormatSymbols(const Locale& locale,  | 
280  |  |                                      const char *type,  | 
281  |  |                                      UErrorCode& status)  | 
282  | 0  |     : UObject()  | 
283  | 0  | { | 
284  | 0  |   initializeData(locale, type,  status);  | 
285  | 0  | }  | 
286  |  |  | 
287  |  | DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)  | 
288  | 0  |     : UObject()  | 
289  | 0  | { | 
290  | 0  |   initializeData(Locale::getDefault(), type, status, TRUE);  | 
291  | 0  | }  | 
292  |  |  | 
293  |  | DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)  | 
294  | 0  |     : UObject(other)  | 
295  | 0  | { | 
296  | 0  |     copyData(other);  | 
297  | 0  | }  | 
298  |  |  | 
299  |  | void  | 
300  |  | DateFormatSymbols::assignArray(UnicodeString*& dstArray,  | 
301  |  |                                int32_t& dstCount,  | 
302  |  |                                const UnicodeString* srcArray,  | 
303  |  |                                int32_t srcCount)  | 
304  | 0  | { | 
305  |  |     // assignArray() is only called by copyData() and initializeData(), which in turn  | 
306  |  |     // implements the copy constructor and the assignment operator.  | 
307  |  |     // All strings in a DateFormatSymbols object are created in one of the following  | 
308  |  |     // three ways that all allow to safely use UnicodeString::fastCopyFrom():  | 
309  |  |     // - readonly-aliases from resource bundles  | 
310  |  |     // - readonly-aliases or allocated strings from constants  | 
311  |  |     // - safely cloned strings (with owned buffers) from setXYZ() functions  | 
312  |  |     //  | 
313  |  |     // Note that this is true for as long as DateFormatSymbols can be constructed  | 
314  |  |     // only from a locale bundle or set via the cloning API,  | 
315  |  |     // *and* for as long as all the strings are in *private* fields, preventing  | 
316  |  |     // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()).  | 
317  | 0  |     dstCount = srcCount;  | 
318  | 0  |     dstArray = newUnicodeStringArray(srcCount);  | 
319  | 0  |     if(dstArray != NULL) { | 
320  | 0  |         int32_t i;  | 
321  | 0  |         for(i=0; i<srcCount; ++i) { | 
322  | 0  |             dstArray[i].fastCopyFrom(srcArray[i]);  | 
323  | 0  |         }  | 
324  | 0  |     }  | 
325  | 0  | }  | 
326  |  |  | 
327  |  | /**  | 
328  |  |  * Create a copy, in fZoneStrings, of the given zone strings array.  The  | 
329  |  |  * member variables fZoneStringsRowCount and fZoneStringsColCount should  | 
330  |  |  * be set already by the caller.  | 
331  |  |  */  | 
332  |  | void  | 
333  |  | DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)  | 
334  | 0  | { | 
335  | 0  |     int32_t row, col;  | 
336  | 0  |     UBool failed = FALSE;  | 
337  |  | 
  | 
338  | 0  |     fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));  | 
339  | 0  |     if (fZoneStrings != NULL) { | 
340  | 0  |         for (row=0; row<fZoneStringsRowCount; ++row)  | 
341  | 0  |         { | 
342  | 0  |             fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount);  | 
343  | 0  |             if (fZoneStrings[row] == NULL) { | 
344  | 0  |                 failed = TRUE;  | 
345  | 0  |                 break;  | 
346  | 0  |             }  | 
347  | 0  |             for (col=0; col<fZoneStringsColCount; ++col) { | 
348  |  |                 // fastCopyFrom() - see assignArray comments  | 
349  | 0  |                 fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);  | 
350  | 0  |             }  | 
351  | 0  |         }  | 
352  | 0  |     }  | 
353  |  |     // If memory allocation failed, roll back and delete fZoneStrings  | 
354  | 0  |     if (failed) { | 
355  | 0  |         for (int i = row; i >= 0; i--) { | 
356  | 0  |             delete[] fZoneStrings[i];  | 
357  | 0  |         }  | 
358  | 0  |         uprv_free(fZoneStrings);  | 
359  | 0  |         fZoneStrings = NULL;  | 
360  | 0  |     }  | 
361  | 0  | }  | 
362  |  |  | 
363  |  | /**  | 
364  |  |  * Copy all of the other's data to this.  | 
365  |  |  */  | 
366  |  | void  | 
367  | 0  | DateFormatSymbols::copyData(const DateFormatSymbols& other) { | 
368  | 0  |     UErrorCode status = U_ZERO_ERROR;  | 
369  | 0  |     U_LOCALE_BASED(locBased, *this);  | 
370  | 0  |     locBased.setLocaleIDs(  | 
371  | 0  |         other.getLocale(ULOC_VALID_LOCALE, status),  | 
372  | 0  |         other.getLocale(ULOC_ACTUAL_LOCALE, status));  | 
373  | 0  |     assignArray(fEras, fErasCount, other.fEras, other.fErasCount);  | 
374  | 0  |     assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);  | 
375  | 0  |     assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);  | 
376  | 0  |     assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);  | 
377  | 0  |     assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);  | 
378  | 0  |     assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);  | 
379  | 0  |     assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount);  | 
380  | 0  |     assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount);  | 
381  | 0  |     assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount);  | 
382  | 0  |     assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount);  | 
383  | 0  |     assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount);  | 
384  | 0  |     assignArray(fShorterWeekdays, fShorterWeekdaysCount, other.fShorterWeekdays, other.fShorterWeekdaysCount);  | 
385  | 0  |     assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount);  | 
386  | 0  |     assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount);  | 
387  | 0  |     assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount);  | 
388  | 0  |     assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount);  | 
389  | 0  |     assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);  | 
390  | 0  |     assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);  | 
391  | 0  |     assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount );  | 
392  | 0  |     fTimeSeparator.fastCopyFrom(other.fTimeSeparator);  // fastCopyFrom() - see assignArray comments  | 
393  | 0  |     assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);  | 
394  | 0  |     assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);  | 
395  | 0  |     assignArray(fNarrowQuarters, fNarrowQuartersCount, other.fNarrowQuarters, other.fNarrowQuartersCount);  | 
396  | 0  |     assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount);  | 
397  | 0  |     assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount);  | 
398  | 0  |     assignArray(fStandaloneNarrowQuarters, fStandaloneNarrowQuartersCount, other.fStandaloneNarrowQuarters, other.fStandaloneNarrowQuartersCount);  | 
399  | 0  |     assignArray(fWideDayPeriods, fWideDayPeriodsCount,  | 
400  | 0  |                 other.fWideDayPeriods, other.fWideDayPeriodsCount);  | 
401  | 0  |     assignArray(fNarrowDayPeriods, fNarrowDayPeriodsCount,  | 
402  | 0  |                 other.fNarrowDayPeriods, other.fNarrowDayPeriodsCount);  | 
403  | 0  |     assignArray(fAbbreviatedDayPeriods, fAbbreviatedDayPeriodsCount,  | 
404  | 0  |                 other.fAbbreviatedDayPeriods, other.fAbbreviatedDayPeriodsCount);  | 
405  | 0  |     assignArray(fStandaloneWideDayPeriods, fStandaloneWideDayPeriodsCount,  | 
406  | 0  |                 other.fStandaloneWideDayPeriods, other.fStandaloneWideDayPeriodsCount);  | 
407  | 0  |     assignArray(fStandaloneNarrowDayPeriods, fStandaloneNarrowDayPeriodsCount,  | 
408  | 0  |                 other.fStandaloneNarrowDayPeriods, other.fStandaloneNarrowDayPeriodsCount);  | 
409  | 0  |     assignArray(fStandaloneAbbreviatedDayPeriods, fStandaloneAbbreviatedDayPeriodsCount,  | 
410  | 0  |                 other.fStandaloneAbbreviatedDayPeriods, other.fStandaloneAbbreviatedDayPeriodsCount);  | 
411  | 0  |     if (other.fLeapMonthPatterns != NULL) { | 
412  | 0  |         assignArray(fLeapMonthPatterns, fLeapMonthPatternsCount, other.fLeapMonthPatterns, other.fLeapMonthPatternsCount);  | 
413  | 0  |     } else { | 
414  | 0  |         fLeapMonthPatterns = NULL;  | 
415  | 0  |         fLeapMonthPatternsCount = 0;  | 
416  | 0  |     }  | 
417  | 0  |     if (other.fShortYearNames != NULL) { | 
418  | 0  |         assignArray(fShortYearNames, fShortYearNamesCount, other.fShortYearNames, other.fShortYearNamesCount);  | 
419  | 0  |     } else { | 
420  | 0  |         fShortYearNames = NULL;  | 
421  | 0  |         fShortYearNamesCount = 0;  | 
422  | 0  |     }  | 
423  | 0  |     if (other.fShortZodiacNames != NULL) { | 
424  | 0  |         assignArray(fShortZodiacNames, fShortZodiacNamesCount, other.fShortZodiacNames, other.fShortZodiacNamesCount);  | 
425  | 0  |     } else { | 
426  | 0  |         fShortZodiacNames = NULL;  | 
427  | 0  |         fShortZodiacNamesCount = 0;  | 
428  | 0  |     }  | 
429  |  | 
  | 
430  | 0  |     if (other.fZoneStrings != NULL) { | 
431  | 0  |         fZoneStringsColCount = other.fZoneStringsColCount;  | 
432  | 0  |         fZoneStringsRowCount = other.fZoneStringsRowCount;  | 
433  | 0  |         createZoneStrings((const UnicodeString**)other.fZoneStrings);  | 
434  |  | 
  | 
435  | 0  |     } else { | 
436  | 0  |         fZoneStrings = NULL;  | 
437  | 0  |         fZoneStringsColCount = 0;  | 
438  | 0  |         fZoneStringsRowCount = 0;  | 
439  | 0  |     }  | 
440  | 0  |     fZSFLocale = other.fZSFLocale;  | 
441  |  |     // Other zone strings data is created on demand  | 
442  | 0  |     fLocaleZoneStrings = NULL;  | 
443  |  |  | 
444  |  |     // fastCopyFrom() - see assignArray comments  | 
445  | 0  |     fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);  | 
446  |  | 
  | 
447  | 0  |     uprv_memcpy(fCapitalization, other.fCapitalization, sizeof(fCapitalization));  | 
448  | 0  | }  | 
449  |  |  | 
450  |  | /**  | 
451  |  |  * Assignment operator.  | 
452  |  |  */  | 
453  |  | DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)  | 
454  | 0  | { | 
455  | 0  |     if (this == &other) { return *this; }  // self-assignment: no-op | 
456  | 0  |     dispose();  | 
457  | 0  |     copyData(other);  | 
458  |  | 
  | 
459  | 0  |     return *this;  | 
460  | 0  | }  | 
461  |  |  | 
462  |  | DateFormatSymbols::~DateFormatSymbols()  | 
463  | 0  | { | 
464  | 0  |     dispose();  | 
465  | 0  | }  | 
466  |  |  | 
467  |  | void DateFormatSymbols::dispose()  | 
468  | 0  | { | 
469  | 0  |     delete[] fEras;  | 
470  | 0  |     delete[] fEraNames;  | 
471  | 0  |     delete[] fNarrowEras;  | 
472  | 0  |     delete[] fMonths;  | 
473  | 0  |     delete[] fShortMonths;  | 
474  | 0  |     delete[] fNarrowMonths;  | 
475  | 0  |     delete[] fStandaloneMonths;  | 
476  | 0  |     delete[] fStandaloneShortMonths;  | 
477  | 0  |     delete[] fStandaloneNarrowMonths;  | 
478  | 0  |     delete[] fWeekdays;  | 
479  | 0  |     delete[] fShortWeekdays;  | 
480  | 0  |     delete[] fShorterWeekdays;  | 
481  | 0  |     delete[] fNarrowWeekdays;  | 
482  | 0  |     delete[] fStandaloneWeekdays;  | 
483  | 0  |     delete[] fStandaloneShortWeekdays;  | 
484  | 0  |     delete[] fStandaloneShorterWeekdays;  | 
485  | 0  |     delete[] fStandaloneNarrowWeekdays;  | 
486  | 0  |     delete[] fAmPms;  | 
487  | 0  |     delete[] fNarrowAmPms;  | 
488  | 0  |     delete[] fQuarters;  | 
489  | 0  |     delete[] fShortQuarters;  | 
490  | 0  |     delete[] fNarrowQuarters;  | 
491  | 0  |     delete[] fStandaloneQuarters;  | 
492  | 0  |     delete[] fStandaloneShortQuarters;  | 
493  | 0  |     delete[] fStandaloneNarrowQuarters;  | 
494  | 0  |     delete[] fLeapMonthPatterns;  | 
495  | 0  |     delete[] fShortYearNames;  | 
496  | 0  |     delete[] fShortZodiacNames;  | 
497  | 0  |     delete[] fAbbreviatedDayPeriods;  | 
498  | 0  |     delete[] fWideDayPeriods;  | 
499  | 0  |     delete[] fNarrowDayPeriods;  | 
500  | 0  |     delete[] fStandaloneAbbreviatedDayPeriods;  | 
501  | 0  |     delete[] fStandaloneWideDayPeriods;  | 
502  | 0  |     delete[] fStandaloneNarrowDayPeriods;  | 
503  |  | 
  | 
504  | 0  |     disposeZoneStrings();  | 
505  | 0  | }  | 
506  |  |  | 
507  |  | void DateFormatSymbols::disposeZoneStrings()  | 
508  | 0  | { | 
509  | 0  |     if (fZoneStrings) { | 
510  | 0  |         for (int32_t row = 0; row < fZoneStringsRowCount; ++row) { | 
511  | 0  |             delete[] fZoneStrings[row];  | 
512  | 0  |         }  | 
513  | 0  |         uprv_free(fZoneStrings);  | 
514  | 0  |     }  | 
515  | 0  |     if (fLocaleZoneStrings) { | 
516  | 0  |         for (int32_t row = 0; row < fZoneStringsRowCount; ++row) { | 
517  | 0  |             delete[] fLocaleZoneStrings[row];  | 
518  | 0  |         }  | 
519  | 0  |         uprv_free(fLocaleZoneStrings);  | 
520  | 0  |     }  | 
521  |  | 
  | 
522  | 0  |     fZoneStrings = NULL;  | 
523  | 0  |     fLocaleZoneStrings = NULL;  | 
524  | 0  |     fZoneStringsRowCount = 0;  | 
525  | 0  |     fZoneStringsColCount = 0;  | 
526  | 0  | }  | 
527  |  |  | 
528  |  | UBool  | 
529  |  | DateFormatSymbols::arrayCompare(const UnicodeString* array1,  | 
530  |  |                                 const UnicodeString* array2,  | 
531  |  |                                 int32_t count)  | 
532  | 0  | { | 
533  | 0  |     if (array1 == array2) return TRUE;  | 
534  | 0  |     while (count>0)  | 
535  | 0  |     { | 
536  | 0  |         --count;  | 
537  | 0  |         if (array1[count] != array2[count]) return FALSE;  | 
538  | 0  |     }  | 
539  | 0  |     return TRUE;  | 
540  | 0  | }  | 
541  |  |  | 
542  |  | bool  | 
543  |  | DateFormatSymbols::operator==(const DateFormatSymbols& other) const  | 
544  | 0  | { | 
545  |  |     // First do cheap comparisons  | 
546  | 0  |     if (this == &other) { | 
547  | 0  |         return TRUE;  | 
548  | 0  |     }  | 
549  | 0  |     if (fErasCount == other.fErasCount &&  | 
550  | 0  |         fEraNamesCount == other.fEraNamesCount &&  | 
551  | 0  |         fNarrowErasCount == other.fNarrowErasCount &&  | 
552  | 0  |         fMonthsCount == other.fMonthsCount &&  | 
553  | 0  |         fShortMonthsCount == other.fShortMonthsCount &&  | 
554  | 0  |         fNarrowMonthsCount == other.fNarrowMonthsCount &&  | 
555  | 0  |         fStandaloneMonthsCount == other.fStandaloneMonthsCount &&  | 
556  | 0  |         fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount &&  | 
557  | 0  |         fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount &&  | 
558  | 0  |         fWeekdaysCount == other.fWeekdaysCount &&  | 
559  | 0  |         fShortWeekdaysCount == other.fShortWeekdaysCount &&  | 
560  | 0  |         fShorterWeekdaysCount == other.fShorterWeekdaysCount &&  | 
561  | 0  |         fNarrowWeekdaysCount == other.fNarrowWeekdaysCount &&  | 
562  | 0  |         fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount &&  | 
563  | 0  |         fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount &&  | 
564  | 0  |         fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount &&  | 
565  | 0  |         fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&  | 
566  | 0  |         fAmPmsCount == other.fAmPmsCount &&  | 
567  | 0  |         fNarrowAmPmsCount == other.fNarrowAmPmsCount &&  | 
568  | 0  |         fQuartersCount == other.fQuartersCount &&  | 
569  | 0  |         fShortQuartersCount == other.fShortQuartersCount &&  | 
570  | 0  |         fNarrowQuartersCount == other.fNarrowQuartersCount &&  | 
571  | 0  |         fStandaloneQuartersCount == other.fStandaloneQuartersCount &&  | 
572  | 0  |         fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount &&  | 
573  | 0  |         fStandaloneNarrowQuartersCount == other.fStandaloneNarrowQuartersCount &&  | 
574  | 0  |         fLeapMonthPatternsCount == other.fLeapMonthPatternsCount &&  | 
575  | 0  |         fShortYearNamesCount == other.fShortYearNamesCount &&  | 
576  | 0  |         fShortZodiacNamesCount == other.fShortZodiacNamesCount &&  | 
577  | 0  |         fAbbreviatedDayPeriodsCount == other.fAbbreviatedDayPeriodsCount &&  | 
578  | 0  |         fWideDayPeriodsCount == other.fWideDayPeriodsCount &&  | 
579  | 0  |         fNarrowDayPeriodsCount == other.fNarrowDayPeriodsCount &&  | 
580  | 0  |         fStandaloneAbbreviatedDayPeriodsCount == other.fStandaloneAbbreviatedDayPeriodsCount &&  | 
581  | 0  |         fStandaloneWideDayPeriodsCount == other.fStandaloneWideDayPeriodsCount &&  | 
582  | 0  |         fStandaloneNarrowDayPeriodsCount == other.fStandaloneNarrowDayPeriodsCount &&  | 
583  | 0  |         (uprv_memcmp(fCapitalization, other.fCapitalization, sizeof(fCapitalization))==0))  | 
584  | 0  |     { | 
585  |  |         // Now compare the arrays themselves  | 
586  | 0  |         if (arrayCompare(fEras, other.fEras, fErasCount) &&  | 
587  | 0  |             arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&  | 
588  | 0  |             arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) &&  | 
589  | 0  |             arrayCompare(fMonths, other.fMonths, fMonthsCount) &&  | 
590  | 0  |             arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&  | 
591  | 0  |             arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&  | 
592  | 0  |             arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) &&  | 
593  | 0  |             arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) &&  | 
594  | 0  |             arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) &&  | 
595  | 0  |             arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&  | 
596  | 0  |             arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&  | 
597  | 0  |             arrayCompare(fShorterWeekdays, other.fShorterWeekdays, fShorterWeekdaysCount) &&  | 
598  | 0  |             arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) &&  | 
599  | 0  |             arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) &&  | 
600  | 0  |             arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) &&  | 
601  | 0  |             arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) &&  | 
602  | 0  |             arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&  | 
603  | 0  |             arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&  | 
604  | 0  |             arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) &&  | 
605  | 0  |             fTimeSeparator == other.fTimeSeparator &&  | 
606  | 0  |             arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&  | 
607  | 0  |             arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&  | 
608  | 0  |             arrayCompare(fNarrowQuarters, other.fNarrowQuarters, fNarrowQuartersCount) &&  | 
609  | 0  |             arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) &&  | 
610  | 0  |             arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount) &&  | 
611  | 0  |             arrayCompare(fStandaloneNarrowQuarters, other.fStandaloneNarrowQuarters, fStandaloneNarrowQuartersCount) &&  | 
612  | 0  |             arrayCompare(fLeapMonthPatterns, other.fLeapMonthPatterns, fLeapMonthPatternsCount) &&  | 
613  | 0  |             arrayCompare(fShortYearNames, other.fShortYearNames, fShortYearNamesCount) &&  | 
614  | 0  |             arrayCompare(fShortZodiacNames, other.fShortZodiacNames, fShortZodiacNamesCount) &&  | 
615  | 0  |             arrayCompare(fAbbreviatedDayPeriods, other.fAbbreviatedDayPeriods, fAbbreviatedDayPeriodsCount) &&  | 
616  | 0  |             arrayCompare(fWideDayPeriods, other.fWideDayPeriods, fWideDayPeriodsCount) &&  | 
617  | 0  |             arrayCompare(fNarrowDayPeriods, other.fNarrowDayPeriods, fNarrowDayPeriodsCount) &&  | 
618  | 0  |             arrayCompare(fStandaloneAbbreviatedDayPeriods, other.fStandaloneAbbreviatedDayPeriods,  | 
619  | 0  |                          fStandaloneAbbreviatedDayPeriodsCount) &&  | 
620  | 0  |             arrayCompare(fStandaloneWideDayPeriods, other.fStandaloneWideDayPeriods,  | 
621  | 0  |                          fStandaloneWideDayPeriodsCount) &&  | 
622  | 0  |             arrayCompare(fStandaloneNarrowDayPeriods, other.fStandaloneNarrowDayPeriods,  | 
623  | 0  |                          fStandaloneWideDayPeriodsCount))  | 
624  | 0  |         { | 
625  |  |             // Compare the contents of fZoneStrings  | 
626  | 0  |             if (fZoneStrings == NULL && other.fZoneStrings == NULL) { | 
627  | 0  |                 if (fZSFLocale == other.fZSFLocale) { | 
628  | 0  |                     return TRUE;  | 
629  | 0  |                 }  | 
630  | 0  |             } else if (fZoneStrings != NULL && other.fZoneStrings != NULL) { | 
631  | 0  |                 if (fZoneStringsRowCount == other.fZoneStringsRowCount  | 
632  | 0  |                     && fZoneStringsColCount == other.fZoneStringsColCount) { | 
633  | 0  |                     UBool cmpres = TRUE;  | 
634  | 0  |                     for (int32_t i = 0; (i < fZoneStringsRowCount) && cmpres; i++) { | 
635  | 0  |                         cmpres = arrayCompare(fZoneStrings[i], other.fZoneStrings[i], fZoneStringsColCount);  | 
636  | 0  |                     }  | 
637  | 0  |                     return cmpres;  | 
638  | 0  |                 }  | 
639  | 0  |             }  | 
640  | 0  |             return FALSE;  | 
641  | 0  |         }  | 
642  | 0  |     }  | 
643  | 0  |     return FALSE;  | 
644  | 0  | }  | 
645  |  |  | 
646  |  | //------------------------------------------------------  | 
647  |  |  | 
648  |  | const UnicodeString*  | 
649  |  | DateFormatSymbols::getEras(int32_t &count) const  | 
650  | 0  | { | 
651  | 0  |     count = fErasCount;  | 
652  | 0  |     return fEras;  | 
653  | 0  | }  | 
654  |  |  | 
655  |  | const UnicodeString*  | 
656  |  | DateFormatSymbols::getEraNames(int32_t &count) const  | 
657  | 0  | { | 
658  | 0  |     count = fEraNamesCount;  | 
659  | 0  |     return fEraNames;  | 
660  | 0  | }  | 
661  |  |  | 
662  |  | const UnicodeString*  | 
663  |  | DateFormatSymbols::getNarrowEras(int32_t &count) const  | 
664  | 0  | { | 
665  | 0  |     count = fNarrowErasCount;  | 
666  | 0  |     return fNarrowEras;  | 
667  | 0  | }  | 
668  |  |  | 
669  |  | const UnicodeString*  | 
670  |  | DateFormatSymbols::getMonths(int32_t &count) const  | 
671  | 0  | { | 
672  | 0  |     count = fMonthsCount;  | 
673  | 0  |     return fMonths;  | 
674  | 0  | }  | 
675  |  |  | 
676  |  | const UnicodeString*  | 
677  |  | DateFormatSymbols::getShortMonths(int32_t &count) const  | 
678  | 0  | { | 
679  | 0  |     count = fShortMonthsCount;  | 
680  | 0  |     return fShortMonths;  | 
681  | 0  | }  | 
682  |  |  | 
683  |  | const UnicodeString*  | 
684  |  | DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const  | 
685  | 0  | { | 
686  | 0  |     UnicodeString *returnValue = NULL;  | 
687  |  | 
  | 
688  | 0  |     switch (context) { | 
689  | 0  |     case FORMAT :  | 
690  | 0  |         switch(width) { | 
691  | 0  |         case WIDE :  | 
692  | 0  |             count = fMonthsCount;  | 
693  | 0  |             returnValue = fMonths;  | 
694  | 0  |             break;  | 
695  | 0  |         case ABBREVIATED :  | 
696  | 0  |         case SHORT : // no month data for this, defaults to ABBREVIATED  | 
697  | 0  |             count = fShortMonthsCount;  | 
698  | 0  |             returnValue = fShortMonths;  | 
699  | 0  |             break;  | 
700  | 0  |         case NARROW :  | 
701  | 0  |             count = fNarrowMonthsCount;  | 
702  | 0  |             returnValue = fNarrowMonths;  | 
703  | 0  |             break;  | 
704  | 0  |         case DT_WIDTH_COUNT :  | 
705  | 0  |             break;  | 
706  | 0  |         }  | 
707  | 0  |         break;  | 
708  | 0  |     case STANDALONE :  | 
709  | 0  |         switch(width) { | 
710  | 0  |         case WIDE :  | 
711  | 0  |             count = fStandaloneMonthsCount;  | 
712  | 0  |             returnValue = fStandaloneMonths;  | 
713  | 0  |             break;  | 
714  | 0  |         case ABBREVIATED :  | 
715  | 0  |         case SHORT : // no month data for this, defaults to ABBREVIATED  | 
716  | 0  |             count = fStandaloneShortMonthsCount;  | 
717  | 0  |             returnValue = fStandaloneShortMonths;  | 
718  | 0  |             break;  | 
719  | 0  |         case NARROW :  | 
720  | 0  |             count = fStandaloneNarrowMonthsCount;  | 
721  | 0  |             returnValue = fStandaloneNarrowMonths;  | 
722  | 0  |             break;  | 
723  | 0  |         case DT_WIDTH_COUNT :  | 
724  | 0  |             break;  | 
725  | 0  |         }  | 
726  | 0  |         break;  | 
727  | 0  |     case DT_CONTEXT_COUNT :  | 
728  | 0  |         break;  | 
729  | 0  |     }  | 
730  | 0  |     return returnValue;  | 
731  | 0  | }  | 
732  |  |  | 
733  |  | const UnicodeString*  | 
734  |  | DateFormatSymbols::getWeekdays(int32_t &count) const  | 
735  | 0  | { | 
736  | 0  |     count = fWeekdaysCount;  | 
737  | 0  |     return fWeekdays;  | 
738  | 0  | }  | 
739  |  |  | 
740  |  | const UnicodeString*  | 
741  |  | DateFormatSymbols::getShortWeekdays(int32_t &count) const  | 
742  | 0  | { | 
743  | 0  |     count = fShortWeekdaysCount;  | 
744  | 0  |     return fShortWeekdays;  | 
745  | 0  | }  | 
746  |  |  | 
747  |  | const UnicodeString*  | 
748  |  | DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const  | 
749  | 0  | { | 
750  | 0  |     UnicodeString *returnValue = NULL;  | 
751  | 0  |     switch (context) { | 
752  | 0  |     case FORMAT :  | 
753  | 0  |         switch(width) { | 
754  | 0  |             case WIDE :  | 
755  | 0  |                 count = fWeekdaysCount;  | 
756  | 0  |                 returnValue = fWeekdays;  | 
757  | 0  |                 break;  | 
758  | 0  |             case ABBREVIATED :  | 
759  | 0  |                 count = fShortWeekdaysCount;  | 
760  | 0  |                 returnValue = fShortWeekdays;  | 
761  | 0  |                 break;  | 
762  | 0  |             case SHORT :  | 
763  | 0  |                 count = fShorterWeekdaysCount;  | 
764  | 0  |                 returnValue = fShorterWeekdays;  | 
765  | 0  |                 break;  | 
766  | 0  |             case NARROW :  | 
767  | 0  |                 count = fNarrowWeekdaysCount;  | 
768  | 0  |                 returnValue = fNarrowWeekdays;  | 
769  | 0  |                 break;  | 
770  | 0  |             case DT_WIDTH_COUNT :  | 
771  | 0  |                 break;  | 
772  | 0  |         }  | 
773  | 0  |         break;  | 
774  | 0  |     case STANDALONE :  | 
775  | 0  |         switch(width) { | 
776  | 0  |             case WIDE :  | 
777  | 0  |                 count = fStandaloneWeekdaysCount;  | 
778  | 0  |                 returnValue = fStandaloneWeekdays;  | 
779  | 0  |                 break;  | 
780  | 0  |             case ABBREVIATED :  | 
781  | 0  |                 count = fStandaloneShortWeekdaysCount;  | 
782  | 0  |                 returnValue = fStandaloneShortWeekdays;  | 
783  | 0  |                 break;  | 
784  | 0  |             case SHORT :  | 
785  | 0  |                 count = fStandaloneShorterWeekdaysCount;  | 
786  | 0  |                 returnValue = fStandaloneShorterWeekdays;  | 
787  | 0  |                 break;  | 
788  | 0  |             case NARROW :  | 
789  | 0  |                 count = fStandaloneNarrowWeekdaysCount;  | 
790  | 0  |                 returnValue = fStandaloneNarrowWeekdays;  | 
791  | 0  |                 break;  | 
792  | 0  |             case DT_WIDTH_COUNT :  | 
793  | 0  |                 break;  | 
794  | 0  |         }  | 
795  | 0  |         break;  | 
796  | 0  |     case DT_CONTEXT_COUNT :  | 
797  | 0  |         break;  | 
798  | 0  |     }  | 
799  | 0  |     return returnValue;  | 
800  | 0  | }  | 
801  |  |  | 
802  |  | const UnicodeString*  | 
803  |  | DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const  | 
804  | 0  | { | 
805  | 0  |     UnicodeString *returnValue = NULL;  | 
806  |  | 
  | 
807  | 0  |     switch (context) { | 
808  | 0  |     case FORMAT :  | 
809  | 0  |         switch(width) { | 
810  | 0  |         case WIDE :  | 
811  | 0  |             count = fQuartersCount;  | 
812  | 0  |             returnValue = fQuarters;  | 
813  | 0  |             break;  | 
814  | 0  |         case ABBREVIATED :  | 
815  | 0  |         case SHORT : // no quarter data for this, defaults to ABBREVIATED  | 
816  | 0  |             count = fShortQuartersCount;  | 
817  | 0  |             returnValue = fShortQuarters;  | 
818  | 0  |             break;  | 
819  | 0  |         case NARROW :  | 
820  | 0  |             count = fNarrowQuartersCount;  | 
821  | 0  |             returnValue = fNarrowQuarters;  | 
822  | 0  |             break;  | 
823  | 0  |         case DT_WIDTH_COUNT :  | 
824  | 0  |             break;  | 
825  | 0  |         }  | 
826  | 0  |         break;  | 
827  | 0  |     case STANDALONE :  | 
828  | 0  |         switch(width) { | 
829  | 0  |         case WIDE :  | 
830  | 0  |             count = fStandaloneQuartersCount;  | 
831  | 0  |             returnValue = fStandaloneQuarters;  | 
832  | 0  |             break;  | 
833  | 0  |         case ABBREVIATED :  | 
834  | 0  |         case SHORT : // no quarter data for this, defaults to ABBREVIATED  | 
835  | 0  |             count = fStandaloneShortQuartersCount;  | 
836  | 0  |             returnValue = fStandaloneShortQuarters;  | 
837  | 0  |             break;  | 
838  | 0  |         case NARROW :  | 
839  | 0  |             count = fStandaloneNarrowQuartersCount;  | 
840  | 0  |             returnValue = fStandaloneNarrowQuarters;  | 
841  | 0  |             break;  | 
842  | 0  |         case DT_WIDTH_COUNT :  | 
843  | 0  |             break;  | 
844  | 0  |         }  | 
845  | 0  |         break;  | 
846  | 0  |     case DT_CONTEXT_COUNT :  | 
847  | 0  |         break;  | 
848  | 0  |     }  | 
849  | 0  |     return returnValue;  | 
850  | 0  | }  | 
851  |  |  | 
852  |  | UnicodeString&  | 
853  |  | DateFormatSymbols::getTimeSeparatorString(UnicodeString& result) const  | 
854  | 0  | { | 
855  |  |     // fastCopyFrom() - see assignArray comments  | 
856  | 0  |     return result.fastCopyFrom(fTimeSeparator);  | 
857  | 0  | }  | 
858  |  |  | 
859  |  | const UnicodeString*  | 
860  |  | DateFormatSymbols::getAmPmStrings(int32_t &count) const  | 
861  | 0  | { | 
862  | 0  |     count = fAmPmsCount;  | 
863  | 0  |     return fAmPms;  | 
864  | 0  | }  | 
865  |  |  | 
866  |  | const UnicodeString*  | 
867  |  | DateFormatSymbols::getLeapMonthPatterns(int32_t &count) const  | 
868  | 0  | { | 
869  | 0  |     count = fLeapMonthPatternsCount;  | 
870  | 0  |     return fLeapMonthPatterns;  | 
871  | 0  | }  | 
872  |  |  | 
873  |  | const UnicodeString*  | 
874  |  | DateFormatSymbols::getYearNames(int32_t& count,  | 
875  |  |                                 DtContextType /*ignored*/, DtWidthType /*ignored*/) const  | 
876  | 0  | { | 
877  | 0  |     count = fShortYearNamesCount;  | 
878  | 0  |     return fShortYearNames;  | 
879  | 0  | }  | 
880  |  |  | 
881  |  | void  | 
882  |  | DateFormatSymbols::setYearNames(const UnicodeString* yearNames, int32_t count,  | 
883  |  |                                 DtContextType context, DtWidthType width)  | 
884  | 0  | { | 
885  | 0  |     if (context == FORMAT && width == ABBREVIATED) { | 
886  | 0  |         if (fShortYearNames) { | 
887  | 0  |             delete[] fShortYearNames;  | 
888  | 0  |         }  | 
889  | 0  |         fShortYearNames = newUnicodeStringArray(count);  | 
890  | 0  |         uprv_arrayCopy(yearNames, fShortYearNames, count);  | 
891  | 0  |         fShortYearNamesCount = count;  | 
892  | 0  |     }  | 
893  | 0  | }  | 
894  |  |  | 
895  |  | const UnicodeString*  | 
896  |  | DateFormatSymbols::getZodiacNames(int32_t& count,  | 
897  |  |                                 DtContextType /*ignored*/, DtWidthType /*ignored*/) const  | 
898  | 0  | { | 
899  | 0  |     count = fShortZodiacNamesCount;  | 
900  | 0  |     return fShortZodiacNames;  | 
901  | 0  | }  | 
902  |  |  | 
903  |  | void  | 
904  |  | DateFormatSymbols::setZodiacNames(const UnicodeString* zodiacNames, int32_t count,  | 
905  |  |                                 DtContextType context, DtWidthType width)  | 
906  | 0  | { | 
907  | 0  |     if (context == FORMAT && width == ABBREVIATED) { | 
908  | 0  |         if (fShortZodiacNames) { | 
909  | 0  |             delete[] fShortZodiacNames;  | 
910  | 0  |         }  | 
911  | 0  |         fShortZodiacNames = newUnicodeStringArray(count);  | 
912  | 0  |         uprv_arrayCopy(zodiacNames, fShortZodiacNames, count);  | 
913  | 0  |         fShortZodiacNamesCount = count;  | 
914  | 0  |     }  | 
915  | 0  | }  | 
916  |  |  | 
917  |  | //------------------------------------------------------  | 
918  |  |  | 
919  |  | void  | 
920  |  | DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)  | 
921  | 0  | { | 
922  |  |     // delete the old list if we own it  | 
923  | 0  |     if (fEras)  | 
924  | 0  |         delete[] fEras;  | 
925  |  |  | 
926  |  |     // we always own the new list, which we create here (we duplicate rather  | 
927  |  |     // than adopting the list passed in)  | 
928  | 0  |     fEras = newUnicodeStringArray(count);  | 
929  | 0  |     uprv_arrayCopy(erasArray,fEras,  count);  | 
930  | 0  |     fErasCount = count;  | 
931  | 0  | }  | 
932  |  |  | 
933  |  | void  | 
934  |  | DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)  | 
935  | 0  | { | 
936  |  |     // delete the old list if we own it  | 
937  | 0  |     if (fEraNames)  | 
938  | 0  |         delete[] fEraNames;  | 
939  |  |  | 
940  |  |     // we always own the new list, which we create here (we duplicate rather  | 
941  |  |     // than adopting the list passed in)  | 
942  | 0  |     fEraNames = newUnicodeStringArray(count);  | 
943  | 0  |     uprv_arrayCopy(eraNamesArray,fEraNames,  count);  | 
944  | 0  |     fEraNamesCount = count;  | 
945  | 0  | }  | 
946  |  |  | 
947  |  | void  | 
948  |  | DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)  | 
949  | 0  | { | 
950  |  |     // delete the old list if we own it  | 
951  | 0  |     if (fNarrowEras)  | 
952  | 0  |         delete[] fNarrowEras;  | 
953  |  |  | 
954  |  |     // we always own the new list, which we create here (we duplicate rather  | 
955  |  |     // than adopting the list passed in)  | 
956  | 0  |     fNarrowEras = newUnicodeStringArray(count);  | 
957  | 0  |     uprv_arrayCopy(narrowErasArray,fNarrowEras,  count);  | 
958  | 0  |     fNarrowErasCount = count;  | 
959  | 0  | }  | 
960  |  |  | 
961  |  | void  | 
962  |  | DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)  | 
963  | 0  | { | 
964  |  |     // delete the old list if we own it  | 
965  | 0  |     if (fMonths)  | 
966  | 0  |         delete[] fMonths;  | 
967  |  |  | 
968  |  |     // we always own the new list, which we create here (we duplicate rather  | 
969  |  |     // than adopting the list passed in)  | 
970  | 0  |     fMonths = newUnicodeStringArray(count);  | 
971  | 0  |     uprv_arrayCopy( monthsArray,fMonths,count);  | 
972  | 0  |     fMonthsCount = count;  | 
973  | 0  | }  | 
974  |  |  | 
975  |  | void  | 
976  |  | DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)  | 
977  | 0  | { | 
978  |  |     // delete the old list if we own it  | 
979  | 0  |     if (fShortMonths)  | 
980  | 0  |         delete[] fShortMonths;  | 
981  |  |  | 
982  |  |     // we always own the new list, which we create here (we duplicate rather  | 
983  |  |     // than adopting the list passed in)  | 
984  | 0  |     fShortMonths = newUnicodeStringArray(count);  | 
985  | 0  |     uprv_arrayCopy(shortMonthsArray,fShortMonths,  count);  | 
986  | 0  |     fShortMonthsCount = count;  | 
987  | 0  | }  | 
988  |  |  | 
989  |  | void  | 
990  |  | DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)  | 
991  | 0  | { | 
992  |  |     // delete the old list if we own it  | 
993  |  |     // we always own the new list, which we create here (we duplicate rather  | 
994  |  |     // than adopting the list passed in)  | 
995  |  | 
  | 
996  | 0  |     switch (context) { | 
997  | 0  |     case FORMAT :  | 
998  | 0  |         switch (width) { | 
999  | 0  |         case WIDE :  | 
1000  | 0  |             if (fMonths)  | 
1001  | 0  |                 delete[] fMonths;  | 
1002  | 0  |             fMonths = newUnicodeStringArray(count);  | 
1003  | 0  |             uprv_arrayCopy( monthsArray,fMonths,count);  | 
1004  | 0  |             fMonthsCount = count;  | 
1005  | 0  |             break;  | 
1006  | 0  |         case ABBREVIATED :  | 
1007  | 0  |             if (fShortMonths)  | 
1008  | 0  |                 delete[] fShortMonths;  | 
1009  | 0  |             fShortMonths = newUnicodeStringArray(count);  | 
1010  | 0  |             uprv_arrayCopy( monthsArray,fShortMonths,count);  | 
1011  | 0  |             fShortMonthsCount = count;  | 
1012  | 0  |             break;  | 
1013  | 0  |         case NARROW :  | 
1014  | 0  |             if (fNarrowMonths)  | 
1015  | 0  |                 delete[] fNarrowMonths;  | 
1016  | 0  |             fNarrowMonths = newUnicodeStringArray(count);  | 
1017  | 0  |             uprv_arrayCopy( monthsArray,fNarrowMonths,count);  | 
1018  | 0  |             fNarrowMonthsCount = count;  | 
1019  | 0  |             break;  | 
1020  | 0  |         default :  | 
1021  | 0  |             break;  | 
1022  | 0  |         }  | 
1023  | 0  |         break;  | 
1024  | 0  |     case STANDALONE :  | 
1025  | 0  |         switch (width) { | 
1026  | 0  |         case WIDE :  | 
1027  | 0  |             if (fStandaloneMonths)  | 
1028  | 0  |                 delete[] fStandaloneMonths;  | 
1029  | 0  |             fStandaloneMonths = newUnicodeStringArray(count);  | 
1030  | 0  |             uprv_arrayCopy( monthsArray,fStandaloneMonths,count);  | 
1031  | 0  |             fStandaloneMonthsCount = count;  | 
1032  | 0  |             break;  | 
1033  | 0  |         case ABBREVIATED :  | 
1034  | 0  |             if (fStandaloneShortMonths)  | 
1035  | 0  |                 delete[] fStandaloneShortMonths;  | 
1036  | 0  |             fStandaloneShortMonths = newUnicodeStringArray(count);  | 
1037  | 0  |             uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count);  | 
1038  | 0  |             fStandaloneShortMonthsCount = count;  | 
1039  | 0  |             break;  | 
1040  | 0  |         case NARROW :  | 
1041  | 0  |            if (fStandaloneNarrowMonths)  | 
1042  | 0  |                 delete[] fStandaloneNarrowMonths;  | 
1043  | 0  |             fStandaloneNarrowMonths = newUnicodeStringArray(count);  | 
1044  | 0  |             uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count);  | 
1045  | 0  |             fStandaloneNarrowMonthsCount = count;  | 
1046  | 0  |             break;  | 
1047  | 0  |         default :  | 
1048  | 0  |             break;  | 
1049  | 0  |         }  | 
1050  | 0  |         break;  | 
1051  | 0  |     case DT_CONTEXT_COUNT :  | 
1052  | 0  |         break;  | 
1053  | 0  |     }  | 
1054  | 0  | }  | 
1055  |  |  | 
1056  |  | void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)  | 
1057  | 0  | { | 
1058  |  |     // delete the old list if we own it  | 
1059  | 0  |     if (fWeekdays)  | 
1060  | 0  |         delete[] fWeekdays;  | 
1061  |  |  | 
1062  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1063  |  |     // than adopting the list passed in)  | 
1064  | 0  |     fWeekdays = newUnicodeStringArray(count);  | 
1065  | 0  |     uprv_arrayCopy(weekdaysArray,fWeekdays,count);  | 
1066  | 0  |     fWeekdaysCount = count;  | 
1067  | 0  | }  | 
1068  |  |  | 
1069  |  | void  | 
1070  |  | DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)  | 
1071  | 0  | { | 
1072  |  |     // delete the old list if we own it  | 
1073  | 0  |     if (fShortWeekdays)  | 
1074  | 0  |         delete[] fShortWeekdays;  | 
1075  |  |  | 
1076  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1077  |  |     // than adopting the list passed in)  | 
1078  | 0  |     fShortWeekdays = newUnicodeStringArray(count);  | 
1079  | 0  |     uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);  | 
1080  | 0  |     fShortWeekdaysCount = count;  | 
1081  | 0  | }  | 
1082  |  |  | 
1083  |  | void  | 
1084  |  | DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)  | 
1085  | 0  | { | 
1086  |  |     // delete the old list if we own it  | 
1087  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1088  |  |     // than adopting the list passed in)  | 
1089  |  | 
  | 
1090  | 0  |     switch (context) { | 
1091  | 0  |     case FORMAT :  | 
1092  | 0  |         switch (width) { | 
1093  | 0  |         case WIDE :  | 
1094  | 0  |             if (fWeekdays)  | 
1095  | 0  |                 delete[] fWeekdays;  | 
1096  | 0  |             fWeekdays = newUnicodeStringArray(count);  | 
1097  | 0  |             uprv_arrayCopy(weekdaysArray, fWeekdays, count);  | 
1098  | 0  |             fWeekdaysCount = count;  | 
1099  | 0  |             break;  | 
1100  | 0  |         case ABBREVIATED :  | 
1101  | 0  |             if (fShortWeekdays)  | 
1102  | 0  |                 delete[] fShortWeekdays;  | 
1103  | 0  |             fShortWeekdays = newUnicodeStringArray(count);  | 
1104  | 0  |             uprv_arrayCopy(weekdaysArray, fShortWeekdays, count);  | 
1105  | 0  |             fShortWeekdaysCount = count;  | 
1106  | 0  |             break;  | 
1107  | 0  |         case SHORT :  | 
1108  | 0  |             if (fShorterWeekdays)  | 
1109  | 0  |                 delete[] fShorterWeekdays;  | 
1110  | 0  |             fShorterWeekdays = newUnicodeStringArray(count);  | 
1111  | 0  |             uprv_arrayCopy(weekdaysArray, fShorterWeekdays, count);  | 
1112  | 0  |             fShorterWeekdaysCount = count;  | 
1113  | 0  |             break;  | 
1114  | 0  |         case NARROW :  | 
1115  | 0  |             if (fNarrowWeekdays)  | 
1116  | 0  |                 delete[] fNarrowWeekdays;  | 
1117  | 0  |             fNarrowWeekdays = newUnicodeStringArray(count);  | 
1118  | 0  |             uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count);  | 
1119  | 0  |             fNarrowWeekdaysCount = count;  | 
1120  | 0  |             break;  | 
1121  | 0  |         case DT_WIDTH_COUNT :  | 
1122  | 0  |             break;  | 
1123  | 0  |         }  | 
1124  | 0  |         break;  | 
1125  | 0  |     case STANDALONE :  | 
1126  | 0  |         switch (width) { | 
1127  | 0  |         case WIDE :  | 
1128  | 0  |             if (fStandaloneWeekdays)  | 
1129  | 0  |                 delete[] fStandaloneWeekdays;  | 
1130  | 0  |             fStandaloneWeekdays = newUnicodeStringArray(count);  | 
1131  | 0  |             uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count);  | 
1132  | 0  |             fStandaloneWeekdaysCount = count;  | 
1133  | 0  |             break;  | 
1134  | 0  |         case ABBREVIATED :  | 
1135  | 0  |             if (fStandaloneShortWeekdays)  | 
1136  | 0  |                 delete[] fStandaloneShortWeekdays;  | 
1137  | 0  |             fStandaloneShortWeekdays = newUnicodeStringArray(count);  | 
1138  | 0  |             uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count);  | 
1139  | 0  |             fStandaloneShortWeekdaysCount = count;  | 
1140  | 0  |             break;  | 
1141  | 0  |         case SHORT :  | 
1142  | 0  |             if (fStandaloneShorterWeekdays)  | 
1143  | 0  |                 delete[] fStandaloneShorterWeekdays;  | 
1144  | 0  |             fStandaloneShorterWeekdays = newUnicodeStringArray(count);  | 
1145  | 0  |             uprv_arrayCopy(weekdaysArray, fStandaloneShorterWeekdays, count);  | 
1146  | 0  |             fStandaloneShorterWeekdaysCount = count;  | 
1147  | 0  |             break;  | 
1148  | 0  |         case NARROW :  | 
1149  | 0  |             if (fStandaloneNarrowWeekdays)  | 
1150  | 0  |                 delete[] fStandaloneNarrowWeekdays;  | 
1151  | 0  |             fStandaloneNarrowWeekdays = newUnicodeStringArray(count);  | 
1152  | 0  |             uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count);  | 
1153  | 0  |             fStandaloneNarrowWeekdaysCount = count;  | 
1154  | 0  |             break;  | 
1155  | 0  |         case DT_WIDTH_COUNT :  | 
1156  | 0  |             break;  | 
1157  | 0  |         }  | 
1158  | 0  |         break;  | 
1159  | 0  |     case DT_CONTEXT_COUNT :  | 
1160  | 0  |         break;  | 
1161  | 0  |     }  | 
1162  | 0  | }  | 
1163  |  |  | 
1164  |  | void  | 
1165  |  | DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)  | 
1166  | 0  | { | 
1167  |  |     // delete the old list if we own it  | 
1168  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1169  |  |     // than adopting the list passed in)  | 
1170  |  | 
  | 
1171  | 0  |     switch (context) { | 
1172  | 0  |     case FORMAT :  | 
1173  | 0  |         switch (width) { | 
1174  | 0  |         case WIDE :  | 
1175  | 0  |             if (fQuarters)  | 
1176  | 0  |                 delete[] fQuarters;  | 
1177  | 0  |             fQuarters = newUnicodeStringArray(count);  | 
1178  | 0  |             uprv_arrayCopy( quartersArray,fQuarters,count);  | 
1179  | 0  |             fQuartersCount = count;  | 
1180  | 0  |             break;  | 
1181  | 0  |         case ABBREVIATED :  | 
1182  | 0  |             if (fShortQuarters)  | 
1183  | 0  |                 delete[] fShortQuarters;  | 
1184  | 0  |             fShortQuarters = newUnicodeStringArray(count);  | 
1185  | 0  |             uprv_arrayCopy( quartersArray,fShortQuarters,count);  | 
1186  | 0  |             fShortQuartersCount = count;  | 
1187  | 0  |             break;  | 
1188  | 0  |         case NARROW :  | 
1189  | 0  |             if (fNarrowQuarters)  | 
1190  | 0  |                 delete[] fNarrowQuarters;  | 
1191  | 0  |             fNarrowQuarters = newUnicodeStringArray(count);  | 
1192  | 0  |             uprv_arrayCopy( quartersArray,fNarrowQuarters,count);  | 
1193  | 0  |             fNarrowQuartersCount = count;  | 
1194  | 0  |             break;  | 
1195  | 0  |         default :  | 
1196  | 0  |             break;  | 
1197  | 0  |         }  | 
1198  | 0  |         break;  | 
1199  | 0  |     case STANDALONE :  | 
1200  | 0  |         switch (width) { | 
1201  | 0  |         case WIDE :  | 
1202  | 0  |             if (fStandaloneQuarters)  | 
1203  | 0  |                 delete[] fStandaloneQuarters;  | 
1204  | 0  |             fStandaloneQuarters = newUnicodeStringArray(count);  | 
1205  | 0  |             uprv_arrayCopy( quartersArray,fStandaloneQuarters,count);  | 
1206  | 0  |             fStandaloneQuartersCount = count;  | 
1207  | 0  |             break;  | 
1208  | 0  |         case ABBREVIATED :  | 
1209  | 0  |             if (fStandaloneShortQuarters)  | 
1210  | 0  |                 delete[] fStandaloneShortQuarters;  | 
1211  | 0  |             fStandaloneShortQuarters = newUnicodeStringArray(count);  | 
1212  | 0  |             uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count);  | 
1213  | 0  |             fStandaloneShortQuartersCount = count;  | 
1214  | 0  |             break;  | 
1215  | 0  |         case NARROW :  | 
1216  | 0  |            if (fStandaloneNarrowQuarters)  | 
1217  | 0  |                 delete[] fStandaloneNarrowQuarters;  | 
1218  | 0  |             fStandaloneNarrowQuarters = newUnicodeStringArray(count);  | 
1219  | 0  |             uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count);  | 
1220  | 0  |             fStandaloneNarrowQuartersCount = count;  | 
1221  | 0  |             break;  | 
1222  | 0  |         default :  | 
1223  | 0  |             break;  | 
1224  | 0  |         }  | 
1225  | 0  |         break;  | 
1226  | 0  |     case DT_CONTEXT_COUNT :  | 
1227  | 0  |         break;  | 
1228  | 0  |     }  | 
1229  | 0  | }  | 
1230  |  |  | 
1231  |  | void  | 
1232  |  | DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)  | 
1233  | 0  | { | 
1234  |  |     // delete the old list if we own it  | 
1235  | 0  |     if (fAmPms) delete[] fAmPms;  | 
1236  |  |  | 
1237  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1238  |  |     // than adopting the list passed in)  | 
1239  | 0  |     fAmPms = newUnicodeStringArray(count);  | 
1240  | 0  |     uprv_arrayCopy(amPmsArray,fAmPms,count);  | 
1241  | 0  |     fAmPmsCount = count;  | 
1242  | 0  | }  | 
1243  |  |  | 
1244  |  | void  | 
1245  |  | DateFormatSymbols::setTimeSeparatorString(const UnicodeString& newTimeSeparator)  | 
1246  | 0  | { | 
1247  | 0  |     fTimeSeparator = newTimeSeparator;  | 
1248  | 0  | }  | 
1249  |  |  | 
1250  |  | const UnicodeString**  | 
1251  |  | DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const  | 
1252  | 0  | { | 
1253  | 0  |     const UnicodeString **result = NULL;  | 
1254  | 0  |     static UMutex LOCK;  | 
1255  |  | 
  | 
1256  | 0  |     umtx_lock(&LOCK);  | 
1257  | 0  |     if (fZoneStrings == NULL) { | 
1258  | 0  |         if (fLocaleZoneStrings == NULL) { | 
1259  | 0  |             ((DateFormatSymbols*)this)->initZoneStringsArray();  | 
1260  | 0  |         }  | 
1261  | 0  |         result = (const UnicodeString**)fLocaleZoneStrings;  | 
1262  | 0  |     } else { | 
1263  | 0  |         result = (const UnicodeString**)fZoneStrings;  | 
1264  | 0  |     }  | 
1265  | 0  |     rowCount = fZoneStringsRowCount;  | 
1266  | 0  |     columnCount = fZoneStringsColCount;  | 
1267  | 0  |     umtx_unlock(&LOCK);  | 
1268  |  | 
  | 
1269  | 0  |     return result;  | 
1270  | 0  | }  | 
1271  |  |  | 
1272  |  | // For now, we include all zones  | 
1273  | 0  | #define ZONE_SET UCAL_ZONE_TYPE_ANY  | 
1274  |  |  | 
1275  |  | // This code must be called within a synchronized block  | 
1276  |  | void  | 
1277  | 0  | DateFormatSymbols::initZoneStringsArray(void) { | 
1278  | 0  |     if (fZoneStrings != NULL || fLocaleZoneStrings != NULL) { | 
1279  | 0  |         return;  | 
1280  | 0  |     }  | 
1281  |  |  | 
1282  | 0  |     UErrorCode status = U_ZERO_ERROR;  | 
1283  |  | 
  | 
1284  | 0  |     StringEnumeration *tzids = NULL;  | 
1285  | 0  |     UnicodeString ** zarray = NULL;  | 
1286  | 0  |     TimeZoneNames *tzNames = NULL;  | 
1287  | 0  |     int32_t rows = 0;  | 
1288  |  | 
  | 
1289  | 0  |     static const UTimeZoneNameType TYPES[] = { | 
1290  | 0  |         UTZNM_LONG_STANDARD, UTZNM_SHORT_STANDARD,  | 
1291  | 0  |         UTZNM_LONG_DAYLIGHT, UTZNM_SHORT_DAYLIGHT  | 
1292  | 0  |     };  | 
1293  | 0  |     static const int32_t NUM_TYPES = 4;  | 
1294  |  | 
  | 
1295  | 0  |     do { // dummy do-while | 
1296  |  | 
  | 
1297  | 0  |         tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status);  | 
1298  | 0  |         rows = tzids->count(status);  | 
1299  | 0  |         if (U_FAILURE(status)) { | 
1300  | 0  |             break;  | 
1301  | 0  |         }  | 
1302  |  |  | 
1303  |  |         // Allocate array  | 
1304  | 0  |         int32_t size = rows * sizeof(UnicodeString*);  | 
1305  | 0  |         zarray = (UnicodeString**)uprv_malloc(size);  | 
1306  | 0  |         if (zarray == NULL) { | 
1307  | 0  |             status = U_MEMORY_ALLOCATION_ERROR;  | 
1308  | 0  |             break;  | 
1309  | 0  |         }  | 
1310  | 0  |         uprv_memset(zarray, 0, size);  | 
1311  |  | 
  | 
1312  | 0  |         tzNames = TimeZoneNames::createInstance(fZSFLocale, status);  | 
1313  | 0  |         tzNames->loadAllDisplayNames(status);  | 
1314  | 0  |         if (U_FAILURE(status)) { break; } | 
1315  |  |  | 
1316  | 0  |         const UnicodeString *tzid;  | 
1317  | 0  |         int32_t i = 0;  | 
1318  | 0  |         UDate now = Calendar::getNow();  | 
1319  | 0  |         UnicodeString tzDispName;  | 
1320  |  | 
  | 
1321  | 0  |         while ((tzid = tzids->snext(status)) != 0) { | 
1322  | 0  |             if (U_FAILURE(status)) { | 
1323  | 0  |                 break;  | 
1324  | 0  |             }  | 
1325  |  |  | 
1326  | 0  |             zarray[i] = new UnicodeString[5];  | 
1327  | 0  |             if (zarray[i] == NULL) { | 
1328  | 0  |                 status = U_MEMORY_ALLOCATION_ERROR;  | 
1329  | 0  |                 break;  | 
1330  | 0  |             }  | 
1331  |  |  | 
1332  | 0  |             zarray[i][0].setTo(*tzid);  | 
1333  | 0  |             tzNames->getDisplayNames(*tzid, TYPES, NUM_TYPES, now, zarray[i]+1, status);  | 
1334  | 0  |             i++;  | 
1335  | 0  |         }  | 
1336  |  | 
  | 
1337  | 0  |     } while (FALSE);  | 
1338  |  |  | 
1339  | 0  |     if (U_FAILURE(status)) { | 
1340  | 0  |         if (zarray) { | 
1341  | 0  |             for (int32_t i = 0; i < rows; i++) { | 
1342  | 0  |                 if (zarray[i]) { | 
1343  | 0  |                     delete[] zarray[i];  | 
1344  | 0  |                 }  | 
1345  | 0  |             }  | 
1346  | 0  |             uprv_free(zarray);  | 
1347  | 0  |             zarray = NULL;  | 
1348  | 0  |         }  | 
1349  | 0  |     }  | 
1350  |  | 
  | 
1351  | 0  |     if (tzNames) { | 
1352  | 0  |         delete tzNames;  | 
1353  | 0  |     }  | 
1354  | 0  |     if (tzids) { | 
1355  | 0  |         delete tzids;  | 
1356  | 0  |     }  | 
1357  |  | 
  | 
1358  | 0  |     fLocaleZoneStrings = zarray;  | 
1359  | 0  |     fZoneStringsRowCount = rows;  | 
1360  | 0  |     fZoneStringsColCount = 1 + NUM_TYPES;  | 
1361  | 0  | }  | 
1362  |  |  | 
1363  |  | void  | 
1364  |  | DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)  | 
1365  | 0  | { | 
1366  |  |     // since deleting a 2-d array is a pain in the butt, we offload that task to  | 
1367  |  |     // a separate function  | 
1368  | 0  |     disposeZoneStrings();  | 
1369  |  |     // we always own the new list, which we create here (we duplicate rather  | 
1370  |  |     // than adopting the list passed in)  | 
1371  | 0  |     fZoneStringsRowCount = rowCount;  | 
1372  | 0  |     fZoneStringsColCount = columnCount;  | 
1373  | 0  |     createZoneStrings((const UnicodeString**)strings);  | 
1374  | 0  | }  | 
1375  |  |  | 
1376  |  | //------------------------------------------------------  | 
1377  |  |  | 
1378  |  | const char16_t * U_EXPORT2  | 
1379  |  | DateFormatSymbols::getPatternUChars(void)  | 
1380  | 0  | { | 
1381  | 0  |     return gPatternChars;  | 
1382  | 0  | }  | 
1383  |  |  | 
1384  |  | UDateFormatField U_EXPORT2  | 
1385  | 0  | DateFormatSymbols::getPatternCharIndex(UChar c) { | 
1386  | 0  |     const UChar *p = u_strchr(gPatternChars, c);  | 
1387  | 0  |     if (p == NULL) { | 
1388  | 0  |         return UDAT_FIELD_COUNT;  | 
1389  | 0  |     } else { | 
1390  | 0  |         return static_cast<UDateFormatField>(p - gPatternChars);  | 
1391  | 0  |     }  | 
1392  | 0  | }  | 
1393  |  |  | 
1394  |  | static const uint64_t kNumericFieldsAlways =  | 
1395  |  |     ((uint64_t)1 << UDAT_YEAR_FIELD) |                      // y  | 
1396  |  |     ((uint64_t)1 << UDAT_DATE_FIELD) |                      // d  | 
1397  |  |     ((uint64_t)1 << UDAT_HOUR_OF_DAY1_FIELD) |              // k  | 
1398  |  |     ((uint64_t)1 << UDAT_HOUR_OF_DAY0_FIELD) |              // H  | 
1399  |  |     ((uint64_t)1 << UDAT_MINUTE_FIELD) |                    // m  | 
1400  |  |     ((uint64_t)1 << UDAT_SECOND_FIELD) |                    // s  | 
1401  |  |     ((uint64_t)1 << UDAT_FRACTIONAL_SECOND_FIELD) |         // S  | 
1402  |  |     ((uint64_t)1 << UDAT_DAY_OF_YEAR_FIELD) |               // D  | 
1403  |  |     ((uint64_t)1 << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) |      // F  | 
1404  |  |     ((uint64_t)1 << UDAT_WEEK_OF_YEAR_FIELD) |              // w  | 
1405  |  |     ((uint64_t)1 << UDAT_WEEK_OF_MONTH_FIELD) |             // W  | 
1406  |  |     ((uint64_t)1 << UDAT_HOUR1_FIELD) |                     // h  | 
1407  |  |     ((uint64_t)1 << UDAT_HOUR0_FIELD) |                     // K  | 
1408  |  |     ((uint64_t)1 << UDAT_YEAR_WOY_FIELD) |                  // Y  | 
1409  |  |     ((uint64_t)1 << UDAT_EXTENDED_YEAR_FIELD) |             // u  | 
1410  |  |     ((uint64_t)1 << UDAT_JULIAN_DAY_FIELD) |                // g  | 
1411  |  |     ((uint64_t)1 << UDAT_MILLISECONDS_IN_DAY_FIELD) |       // A  | 
1412  |  |     ((uint64_t)1 << UDAT_RELATED_YEAR_FIELD);               // r  | 
1413  |  |  | 
1414  |  | static const uint64_t kNumericFieldsForCount12 =  | 
1415  |  |     ((uint64_t)1 << UDAT_MONTH_FIELD) |                     // M or MM  | 
1416  |  |     ((uint64_t)1 << UDAT_DOW_LOCAL_FIELD) |                 // e or ee  | 
1417  |  |     ((uint64_t)1 << UDAT_STANDALONE_DAY_FIELD) |            // c or cc  | 
1418  |  |     ((uint64_t)1 << UDAT_STANDALONE_MONTH_FIELD) |          // L or LL  | 
1419  |  |     ((uint64_t)1 << UDAT_QUARTER_FIELD) |                   // Q or QQ  | 
1420  |  |     ((uint64_t)1 << UDAT_STANDALONE_QUARTER_FIELD);         // q or qq  | 
1421  |  |  | 
1422  |  | UBool U_EXPORT2  | 
1423  | 0  | DateFormatSymbols::isNumericField(UDateFormatField f, int32_t count) { | 
1424  | 0  |     if (f == UDAT_FIELD_COUNT) { | 
1425  | 0  |         return FALSE;  | 
1426  | 0  |     }  | 
1427  | 0  |     uint64_t flag = ((uint64_t)1 << f);  | 
1428  | 0  |     return ((kNumericFieldsAlways & flag) != 0 || ((kNumericFieldsForCount12 & flag) != 0 && count < 3));  | 
1429  | 0  | }  | 
1430  |  |  | 
1431  |  | UBool U_EXPORT2  | 
1432  | 0  | DateFormatSymbols::isNumericPatternChar(UChar c, int32_t count) { | 
1433  | 0  |     return isNumericField(getPatternCharIndex(c), count);  | 
1434  | 0  | }  | 
1435  |  |  | 
1436  |  | //------------------------------------------------------  | 
1437  |  |  | 
1438  |  | UnicodeString&  | 
1439  |  | DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const  | 
1440  | 0  | { | 
1441  |  |     // fastCopyFrom() - see assignArray comments  | 
1442  | 0  |     return result.fastCopyFrom(fLocalPatternChars);  | 
1443  | 0  | }  | 
1444  |  |  | 
1445  |  | //------------------------------------------------------  | 
1446  |  |  | 
1447  |  | void  | 
1448  |  | DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)  | 
1449  | 0  | { | 
1450  | 0  |     fLocalPatternChars = newLocalPatternChars;  | 
1451  | 0  | }  | 
1452  |  |  | 
1453  |  | //------------------------------------------------------  | 
1454  |  |  | 
1455  |  | namespace { | 
1456  |  |  | 
1457  |  | // Constants declarations  | 
1458  |  | static const UChar kCalendarAliasPrefixUChar[] = { | 
1459  |  |     SOLIDUS, CAP_L, CAP_O, CAP_C, CAP_A, CAP_L, CAP_E, SOLIDUS,  | 
1460  |  |     LOW_C, LOW_A, LOW_L, LOW_E, LOW_N, LOW_D, LOW_A, LOW_R, SOLIDUS  | 
1461  |  | };  | 
1462  |  | static const UChar kGregorianTagUChar[] = { | 
1463  |  |     LOW_G, LOW_R, LOW_E, LOW_G, LOW_O, LOW_R, LOW_I, LOW_A, LOW_N  | 
1464  |  | };  | 
1465  |  | static const UChar kVariantTagUChar[] = { | 
1466  |  |     PERCENT, LOW_V, LOW_A, LOW_R, LOW_I, LOW_A, LOW_N, LOW_T  | 
1467  |  | };  | 
1468  |  | static const UChar kLeapTagUChar[] = { | 
1469  |  |     LOW_L, LOW_E, LOW_A, LOW_P  | 
1470  |  | };  | 
1471  |  | static const UChar kCyclicNameSetsTagUChar[] = { | 
1472  |  |     LOW_C, LOW_Y, LOW_C, LOW_L, LOW_I, LOW_C, CAP_N, LOW_A, LOW_M, LOW_E, CAP_S, LOW_E, LOW_T, LOW_S  | 
1473  |  | };  | 
1474  |  | static const UChar kYearsTagUChar[] = { | 
1475  |  |     SOLIDUS, LOW_Y, LOW_E, LOW_A, LOW_R, LOW_S  | 
1476  |  | };  | 
1477  |  | static const UChar kZodiacsUChar[] = { | 
1478  |  |     SOLIDUS, LOW_Z, LOW_O, LOW_D, LOW_I, LOW_A, LOW_C, LOW_S  | 
1479  |  | };  | 
1480  |  | static const UChar kDayPartsTagUChar[] = { | 
1481  |  |     SOLIDUS, LOW_D, LOW_A, LOW_Y, CAP_P, LOW_A, LOW_R, LOW_T, LOW_S  | 
1482  |  | };  | 
1483  |  | static const UChar kFormatTagUChar[] = { | 
1484  |  |     SOLIDUS, LOW_F, LOW_O, LOW_R, LOW_M, LOW_A, LOW_T  | 
1485  |  | };  | 
1486  |  | static const UChar kAbbrTagUChar[] = { | 
1487  |  |     SOLIDUS, LOW_A, LOW_B, LOW_B, LOW_R, LOW_E, LOW_V, LOW_I, LOW_A, LOW_T, LOW_E, LOW_D  | 
1488  |  | };  | 
1489  |  |  | 
1490  |  | // ResourceSink to enumerate all calendar resources  | 
1491  |  | struct CalendarDataSink : public ResourceSink { | 
1492  |  |  | 
1493  |  |     // Enum which specifies the type of alias received, or no alias  | 
1494  |  |     enum AliasType { | 
1495  |  |         SAME_CALENDAR,  | 
1496  |  |         DIFFERENT_CALENDAR,  | 
1497  |  |         GREGORIAN,  | 
1498  |  |         NONE  | 
1499  |  |     };  | 
1500  |  |  | 
1501  |  |     // Data structures to store resources from the current resource bundle  | 
1502  |  |     Hashtable arrays;  | 
1503  |  |     Hashtable arraySizes;  | 
1504  |  |     Hashtable maps;  | 
1505  |  |     /**   | 
1506  |  |      * Whenever there are aliases, the same object will be added twice to 'map'.  | 
1507  |  |      * To avoid double deletion, 'maps' won't take ownership of the objects. Instead,  | 
1508  |  |      * 'mapRefs' will own them and will delete them when CalendarDataSink is deleted.  | 
1509  |  |      */  | 
1510  |  |     MemoryPool<Hashtable> mapRefs;  | 
1511  |  |  | 
1512  |  |     // Paths and the aliases they point to  | 
1513  |  |     UVector aliasPathPairs;  | 
1514  |  |  | 
1515  |  |     // Current and next calendar resource table which should be loaded  | 
1516  |  |     UnicodeString currentCalendarType;  | 
1517  |  |     UnicodeString nextCalendarType;  | 
1518  |  |  | 
1519  |  |     // Resources to visit when enumerating fallback calendars  | 
1520  |  |     LocalPointer<UVector> resourcesToVisit;  | 
1521  |  |  | 
1522  |  |     // Alias' relative path populated whenever an alias is read  | 
1523  |  |     UnicodeString aliasRelativePath;  | 
1524  |  |  | 
1525  |  |     // Initializes CalendarDataSink with default values  | 
1526  |  |     CalendarDataSink(UErrorCode& status)  | 
1527  | 0  |     :   arrays(FALSE, status), arraySizes(FALSE, status), maps(FALSE, status),  | 
1528  | 0  |         mapRefs(),  | 
1529  | 0  |         aliasPathPairs(uprv_deleteUObject, uhash_compareUnicodeString, status),  | 
1530  | 0  |         currentCalendarType(), nextCalendarType(),  | 
1531  | 0  |         resourcesToVisit(NULL), aliasRelativePath() { | 
1532  | 0  |         if (U_FAILURE(status)) { return; } | 
1533  | 0  |     }  | 
1534  |  |     virtual ~CalendarDataSink();  | 
1535  |  |  | 
1536  |  |     // Configure the CalendarSink to visit all the resources  | 
1537  | 0  |     void visitAllResources() { | 
1538  | 0  |         resourcesToVisit.adoptInstead(NULL);  | 
1539  | 0  |     }  | 
1540  |  |  | 
1541  |  |     // Actions to be done before enumerating  | 
1542  | 0  |     void preEnumerate(const UnicodeString &calendarType) { | 
1543  | 0  |         currentCalendarType = calendarType;  | 
1544  | 0  |         nextCalendarType.setToBogus();  | 
1545  | 0  |         aliasPathPairs.removeAllElements();  | 
1546  | 0  |     }  | 
1547  |  |  | 
1548  | 0  |     virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { | 
1549  | 0  |         if (U_FAILURE(errorCode)) { return; } | 
1550  | 0  |         U_ASSERT(!currentCalendarType.isEmpty());  | 
1551  |  |  | 
1552  |  |         // Stores the resources to visit on the next calendar.  | 
1553  | 0  |         LocalPointer<UVector> resourcesToVisitNext(NULL);  | 
1554  | 0  |         ResourceTable calendarData = value.getTable(errorCode);  | 
1555  | 0  |         if (U_FAILURE(errorCode)) { return; } | 
1556  |  |  | 
1557  |  |         // Enumerate all resources for this calendar  | 
1558  | 0  |         for (int i = 0; calendarData.getKeyAndValue(i, key, value); i++) { | 
1559  | 0  |             UnicodeString keyUString(key, -1, US_INV);  | 
1560  |  |  | 
1561  |  |             // == Handle aliases ==  | 
1562  | 0  |             AliasType aliasType = processAliasFromValue(keyUString, value, errorCode);  | 
1563  | 0  |             if (U_FAILURE(errorCode)) { return; } | 
1564  | 0  |             if (aliasType == GREGORIAN) { | 
1565  |  |                 // Ignore aliases to the gregorian calendar, all of its resources will be loaded anyway.  | 
1566  | 0  |                 continue;  | 
1567  |  | 
  | 
1568  | 0  |             } else if (aliasType == DIFFERENT_CALENDAR) { | 
1569  |  |                 // Whenever an alias to the next calendar (except gregorian) is encountered, register the  | 
1570  |  |                 // calendar type it's pointing to  | 
1571  | 0  |                 if (resourcesToVisitNext.isNull()) { | 
1572  | 0  |                     resourcesToVisitNext  | 
1573  | 0  |                         .adoptInsteadAndCheckErrorCode(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, errorCode),  | 
1574  | 0  |                                                        errorCode);  | 
1575  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1576  | 0  |                 }  | 
1577  | 0  |                 LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);  | 
1578  | 0  |                 resourcesToVisitNext->addElementX(aliasRelativePathCopy.getAlias(), errorCode);  | 
1579  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1580  |  |                 // Only release ownership after resourcesToVisitNext takes it (no error happened):  | 
1581  | 0  |                 aliasRelativePathCopy.orphan();  | 
1582  | 0  |                 continue;  | 
1583  |  | 
  | 
1584  | 0  |             } else if (aliasType == SAME_CALENDAR) { | 
1585  |  |                 // Register same-calendar alias  | 
1586  | 0  |                 if (arrays.get(aliasRelativePath) == NULL && maps.get(aliasRelativePath) == NULL) { | 
1587  | 0  |                     LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);  | 
1588  | 0  |                     aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);  | 
1589  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1590  |  |                     // Only release ownership after aliasPathPairs takes it (no error happened):  | 
1591  | 0  |                     aliasRelativePathCopy.orphan();  | 
1592  | 0  |                     LocalPointer<UnicodeString> keyUStringCopy(new UnicodeString(keyUString), errorCode);  | 
1593  | 0  |                     aliasPathPairs.addElementX(keyUStringCopy.getAlias(), errorCode);  | 
1594  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1595  |  |                     // Only release ownership after aliasPathPairs takes it (no error happened):  | 
1596  | 0  |                     keyUStringCopy.orphan();  | 
1597  | 0  |                 }  | 
1598  | 0  |                 continue;  | 
1599  | 0  |             }  | 
1600  |  |  | 
1601  |  |             // Only visit the resources that were referenced by an alias on the previous calendar  | 
1602  |  |             // (AmPmMarkersAbbr is an exception).  | 
1603  | 0  |             if (!resourcesToVisit.isNull() && !resourcesToVisit->isEmpty() && !resourcesToVisit->contains(&keyUString)  | 
1604  | 0  |                 && uprv_strcmp(key, gAmPmMarkersAbbrTag) != 0) { continue; } | 
1605  |  |  | 
1606  |  |             // == Handle data ==  | 
1607  | 0  |             if (uprv_strcmp(key, gAmPmMarkersTag) == 0  | 
1608  | 0  |                 || uprv_strcmp(key, gAmPmMarkersAbbrTag) == 0  | 
1609  | 0  |                 || uprv_strcmp(key, gAmPmMarkersNarrowTag) == 0) { | 
1610  | 0  |                 if (arrays.get(keyUString) == NULL) { | 
1611  | 0  |                     ResourceArray resourceArray = value.getArray(errorCode);  | 
1612  | 0  |                     int32_t arraySize = resourceArray.getSize();  | 
1613  | 0  |                     LocalArray<UnicodeString> stringArray(new UnicodeString[arraySize], errorCode);  | 
1614  | 0  |                     value.getStringArray(stringArray.getAlias(), arraySize, errorCode);  | 
1615  | 0  |                     arrays.put(keyUString, stringArray.orphan(), errorCode);  | 
1616  | 0  |                     arraySizes.puti(keyUString, arraySize, errorCode);  | 
1617  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1618  | 0  |                 }  | 
1619  | 0  |             } else if (uprv_strcmp(key, gErasTag) == 0  | 
1620  | 0  |                        || uprv_strcmp(key, gDayNamesTag) == 0  | 
1621  | 0  |                        || uprv_strcmp(key, gMonthNamesTag) == 0  | 
1622  | 0  |                        || uprv_strcmp(key, gQuartersTag) == 0  | 
1623  | 0  |                        || uprv_strcmp(key, gDayPeriodTag) == 0  | 
1624  | 0  |                        || uprv_strcmp(key, gMonthPatternsTag) == 0  | 
1625  | 0  |                        || uprv_strcmp(key, gCyclicNameSetsTag) == 0) { | 
1626  | 0  |                 processResource(keyUString, key, value, errorCode);  | 
1627  | 0  |             }  | 
1628  | 0  |         }  | 
1629  |  |  | 
1630  |  |         // Apply same-calendar aliases  | 
1631  | 0  |         UBool modified;  | 
1632  | 0  |         do { | 
1633  | 0  |             modified = false;  | 
1634  | 0  |             for (int32_t i = 0; i < aliasPathPairs.size();) { | 
1635  | 0  |                 UBool mod = false;  | 
1636  | 0  |                 UnicodeString *alias = (UnicodeString*)aliasPathPairs[i];  | 
1637  | 0  |                 UnicodeString *aliasArray;  | 
1638  | 0  |                 Hashtable *aliasMap;  | 
1639  | 0  |                 if ((aliasArray = (UnicodeString*)arrays.get(*alias)) != NULL) { | 
1640  | 0  |                     UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1];  | 
1641  | 0  |                     if (arrays.get(*path) == NULL) { | 
1642  |  |                         // Clone the array  | 
1643  | 0  |                         int32_t aliasArraySize = arraySizes.geti(*alias);  | 
1644  | 0  |                         LocalArray<UnicodeString> aliasArrayCopy(new UnicodeString[aliasArraySize], errorCode);  | 
1645  | 0  |                         if (U_FAILURE(errorCode)) { return; } | 
1646  | 0  |                         uprv_arrayCopy(aliasArray, aliasArrayCopy.getAlias(), aliasArraySize);  | 
1647  |  |                         // Put the array on the 'arrays' map  | 
1648  | 0  |                         arrays.put(*path, aliasArrayCopy.orphan(), errorCode);  | 
1649  | 0  |                         arraySizes.puti(*path, aliasArraySize, errorCode);  | 
1650  | 0  |                     }  | 
1651  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1652  | 0  |                     mod = true;  | 
1653  | 0  |                 } else if ((aliasMap = (Hashtable*)maps.get(*alias)) != NULL) { | 
1654  | 0  |                     UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1];  | 
1655  | 0  |                     if (maps.get(*path) == NULL) { | 
1656  | 0  |                         maps.put(*path, aliasMap, errorCode);  | 
1657  | 0  |                     }  | 
1658  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1659  | 0  |                     mod = true;  | 
1660  | 0  |                 }  | 
1661  | 0  |                 if (mod) { | 
1662  | 0  |                     aliasPathPairs.removeElementAt(i + 1);  | 
1663  | 0  |                     aliasPathPairs.removeElementAt(i);  | 
1664  | 0  |                     modified = true;  | 
1665  | 0  |                 } else { | 
1666  | 0  |                     i += 2;  | 
1667  | 0  |                 }  | 
1668  | 0  |             }  | 
1669  | 0  |         } while (modified && !aliasPathPairs.isEmpty());  | 
1670  |  |  | 
1671  |  |         // Set the resources to visit on the next calendar  | 
1672  | 0  |         if (!resourcesToVisitNext.isNull()) { | 
1673  | 0  |             resourcesToVisit = std::move(resourcesToVisitNext);  | 
1674  | 0  |         }  | 
1675  | 0  |     }  | 
1676  |  |  | 
1677  |  |     // Process the nested resource bundle tables  | 
1678  | 0  |     void processResource(UnicodeString &path, const char *key, ResourceValue &value, UErrorCode &errorCode) { | 
1679  | 0  |         if (U_FAILURE(errorCode)) return;  | 
1680  |  |  | 
1681  | 0  |         ResourceTable table = value.getTable(errorCode);  | 
1682  | 0  |         if (U_FAILURE(errorCode)) return;  | 
1683  | 0  |         Hashtable* stringMap = NULL;  | 
1684  |  |  | 
1685  |  |         // Iterate over all the elements of the table and add them to the map  | 
1686  | 0  |         for (int i = 0; table.getKeyAndValue(i, key, value); i++) { | 
1687  | 0  |             UnicodeString keyUString(key, -1, US_INV);  | 
1688  |  |  | 
1689  |  |             // Ignore '%variant' keys  | 
1690  | 0  |             if (keyUString.endsWith(kVariantTagUChar, UPRV_LENGTHOF(kVariantTagUChar))) { | 
1691  | 0  |                 continue;  | 
1692  | 0  |             }  | 
1693  |  |  | 
1694  |  |             // == Handle String elements ==  | 
1695  | 0  |             if (value.getType() == URES_STRING) { | 
1696  |  |                 // We are on a leaf, store the map elements into the stringMap  | 
1697  | 0  |                 if (i == 0) { | 
1698  |  |                     // mapRefs will keep ownership of 'stringMap':  | 
1699  | 0  |                     stringMap = mapRefs.create(FALSE, errorCode);  | 
1700  | 0  |                     if (stringMap == NULL) { | 
1701  | 0  |                         errorCode = U_MEMORY_ALLOCATION_ERROR;  | 
1702  | 0  |                         return;  | 
1703  | 0  |                     }  | 
1704  | 0  |                     maps.put(path, stringMap, errorCode);  | 
1705  | 0  |                     if (U_FAILURE(errorCode)) { return; } | 
1706  | 0  |                     stringMap->setValueDeleter(uprv_deleteUObject);  | 
1707  | 0  |                 }  | 
1708  | 0  |                 U_ASSERT(stringMap != NULL);  | 
1709  | 0  |                 int32_t valueStringSize;  | 
1710  | 0  |                 const UChar *valueString = value.getString(valueStringSize, errorCode);  | 
1711  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1712  | 0  |                 LocalPointer<UnicodeString> valueUString(new UnicodeString(TRUE, valueString, valueStringSize), errorCode);  | 
1713  | 0  |                 stringMap->put(keyUString, valueUString.orphan(), errorCode);  | 
1714  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1715  | 0  |                 continue;  | 
1716  | 0  |             }  | 
1717  | 0  |             U_ASSERT(stringMap == NULL);  | 
1718  |  |  | 
1719  |  |             // Store the current path's length and append the current key to the path.  | 
1720  | 0  |             int32_t pathLength = path.length();  | 
1721  | 0  |             path.append(SOLIDUS).append(keyUString);  | 
1722  |  |  | 
1723  |  |             // In cyclicNameSets ignore everything but years/format/abbreviated  | 
1724  |  |             // and zodiacs/format/abbreviated  | 
1725  | 0  |             if (path.startsWith(kCyclicNameSetsTagUChar, UPRV_LENGTHOF(kCyclicNameSetsTagUChar))) { | 
1726  | 0  |                 UBool skip = TRUE;  | 
1727  | 0  |                 int32_t startIndex = UPRV_LENGTHOF(kCyclicNameSetsTagUChar);  | 
1728  | 0  |                 int32_t length = 0;  | 
1729  | 0  |                 if (startIndex == path.length()  | 
1730  | 0  |                     || path.compare(startIndex, (length = UPRV_LENGTHOF(kZodiacsUChar)), kZodiacsUChar, 0, UPRV_LENGTHOF(kZodiacsUChar)) == 0  | 
1731  | 0  |                     || path.compare(startIndex, (length = UPRV_LENGTHOF(kYearsTagUChar)), kYearsTagUChar, 0, UPRV_LENGTHOF(kYearsTagUChar)) == 0  | 
1732  | 0  |                     || path.compare(startIndex, (length = UPRV_LENGTHOF(kDayPartsTagUChar)), kDayPartsTagUChar, 0, UPRV_LENGTHOF(kDayPartsTagUChar)) == 0) { | 
1733  | 0  |                     startIndex += length;  | 
1734  | 0  |                     length = 0;  | 
1735  | 0  |                     if (startIndex == path.length()  | 
1736  | 0  |                         || path.compare(startIndex, (length = UPRV_LENGTHOF(kFormatTagUChar)), kFormatTagUChar, 0, UPRV_LENGTHOF(kFormatTagUChar)) == 0) { | 
1737  | 0  |                         startIndex += length;  | 
1738  | 0  |                         length = 0;  | 
1739  | 0  |                         if (startIndex == path.length()  | 
1740  | 0  |                             || path.compare(startIndex, (length = UPRV_LENGTHOF(kAbbrTagUChar)), kAbbrTagUChar, 0, UPRV_LENGTHOF(kAbbrTagUChar)) == 0) { | 
1741  | 0  |                             skip = FALSE;  | 
1742  | 0  |                         }  | 
1743  | 0  |                     }  | 
1744  | 0  |                 }  | 
1745  | 0  |                 if (skip) { | 
1746  |  |                     // Drop the latest key on the path and continue  | 
1747  | 0  |                     path.retainBetween(0, pathLength);  | 
1748  | 0  |                     continue;  | 
1749  | 0  |                 }  | 
1750  | 0  |             }  | 
1751  |  |  | 
1752  |  |             // == Handle aliases ==  | 
1753  | 0  |             if (arrays.get(path) != NULL || maps.get(path) != NULL) { | 
1754  |  |                 // Drop the latest key on the path and continue  | 
1755  | 0  |                 path.retainBetween(0, pathLength);  | 
1756  | 0  |                 continue;  | 
1757  | 0  |             }  | 
1758  |  |  | 
1759  | 0  |             AliasType aliasType = processAliasFromValue(path, value, errorCode);  | 
1760  | 0  |             if (U_FAILURE(errorCode)) { return; } | 
1761  | 0  |             if (aliasType == SAME_CALENDAR) { | 
1762  |  |                 // Store the alias path and the current path on aliasPathPairs  | 
1763  | 0  |                 LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);  | 
1764  | 0  |                 aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);  | 
1765  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1766  |  |                 // Only release ownership after aliasPathPairs takes it (no error happened):  | 
1767  | 0  |                 aliasRelativePathCopy.orphan();  | 
1768  | 0  |                 LocalPointer<UnicodeString> pathCopy(new UnicodeString(path), errorCode);  | 
1769  | 0  |                 aliasPathPairs.addElementX(pathCopy.getAlias(), errorCode);  | 
1770  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1771  |  |                 // Only release ownership after aliasPathPairs takes it (no error happened):  | 
1772  | 0  |                 pathCopy.orphan();  | 
1773  |  |  | 
1774  |  |                 // Drop the latest key on the path and continue  | 
1775  | 0  |                 path.retainBetween(0, pathLength);  | 
1776  | 0  |                 continue;  | 
1777  | 0  |             }  | 
1778  | 0  |             U_ASSERT(aliasType == NONE);  | 
1779  |  |  | 
1780  |  |             // == Handle data ==  | 
1781  | 0  |             if (value.getType() == URES_ARRAY) { | 
1782  |  |                 // We are on a leaf, store the array  | 
1783  | 0  |                 ResourceArray rDataArray = value.getArray(errorCode);  | 
1784  | 0  |                 int32_t dataArraySize = rDataArray.getSize();  | 
1785  | 0  |                 LocalArray<UnicodeString> dataArray(new UnicodeString[dataArraySize], errorCode);  | 
1786  | 0  |                 value.getStringArray(dataArray.getAlias(), dataArraySize, errorCode);  | 
1787  | 0  |                 arrays.put(path, dataArray.orphan(), errorCode);  | 
1788  | 0  |                 arraySizes.puti(path, dataArraySize, errorCode);  | 
1789  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1790  | 0  |             } else if (value.getType() == URES_TABLE) { | 
1791  |  |                 // We are not on a leaf, recursively process the subtable.  | 
1792  | 0  |                 processResource(path, key, value, errorCode);  | 
1793  | 0  |                 if (U_FAILURE(errorCode)) { return; } | 
1794  | 0  |             }  | 
1795  |  |  | 
1796  |  |             // Drop the latest key on the path  | 
1797  | 0  |             path.retainBetween(0, pathLength);  | 
1798  | 0  |         }  | 
1799  | 0  |     }  | 
1800  |  |  | 
1801  |  |     // Populates an AliasIdentifier with the alias information contained on the UResource.Value.  | 
1802  |  |     AliasType processAliasFromValue(UnicodeString ¤tRelativePath, ResourceValue &value,  | 
1803  | 0  |                                     UErrorCode &errorCode) { | 
1804  | 0  |         if (U_FAILURE(errorCode)) { return NONE; } | 
1805  |  |  | 
1806  | 0  |         if (value.getType() == URES_ALIAS) { | 
1807  | 0  |             int32_t aliasPathSize;  | 
1808  | 0  |             const UChar* aliasPathUChar = value.getAliasString(aliasPathSize, errorCode);  | 
1809  | 0  |             if (U_FAILURE(errorCode)) { return NONE; } | 
1810  | 0  |             UnicodeString aliasPath(aliasPathUChar, aliasPathSize);  | 
1811  | 0  |             const int32_t aliasPrefixLength = UPRV_LENGTHOF(kCalendarAliasPrefixUChar);  | 
1812  | 0  |             if (aliasPath.startsWith(kCalendarAliasPrefixUChar, aliasPrefixLength)  | 
1813  | 0  |                 && aliasPath.length() > aliasPrefixLength) { | 
1814  | 0  |                 int32_t typeLimit = aliasPath.indexOf(SOLIDUS, aliasPrefixLength);  | 
1815  | 0  |                 if (typeLimit > aliasPrefixLength) { | 
1816  | 0  |                     const UnicodeString aliasCalendarType =  | 
1817  | 0  |                         aliasPath.tempSubStringBetween(aliasPrefixLength, typeLimit);  | 
1818  | 0  |                     aliasRelativePath.setTo(aliasPath, typeLimit + 1, aliasPath.length());  | 
1819  |  | 
  | 
1820  | 0  |                     if (currentCalendarType == aliasCalendarType  | 
1821  | 0  |                         && currentRelativePath != aliasRelativePath) { | 
1822  |  |                         // If we have an alias to the same calendar, the path to the resource must be different  | 
1823  | 0  |                         return SAME_CALENDAR;  | 
1824  |  | 
  | 
1825  | 0  |                     } else if (currentCalendarType != aliasCalendarType  | 
1826  | 0  |                                && currentRelativePath == aliasRelativePath) { | 
1827  |  |                         // If we have an alias to a different calendar, the path to the resource must be the same  | 
1828  | 0  |                         if (aliasCalendarType.compare(kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar)) == 0) { | 
1829  | 0  |                             return GREGORIAN;  | 
1830  | 0  |                         } else if (nextCalendarType.isBogus()) { | 
1831  | 0  |                             nextCalendarType = aliasCalendarType;  | 
1832  | 0  |                             return DIFFERENT_CALENDAR;  | 
1833  | 0  |                         } else if (nextCalendarType == aliasCalendarType) { | 
1834  | 0  |                             return DIFFERENT_CALENDAR;  | 
1835  | 0  |                         }  | 
1836  | 0  |                     }  | 
1837  | 0  |                 }  | 
1838  | 0  |             }  | 
1839  | 0  |             errorCode = U_INTERNAL_PROGRAM_ERROR;  | 
1840  | 0  |             return NONE;  | 
1841  | 0  |         }  | 
1842  | 0  |         return NONE;  | 
1843  | 0  |     }  | 
1844  |  |  | 
1845  |  |     // Deleter function to be used by 'arrays'  | 
1846  | 0  |     static void U_CALLCONV deleteUnicodeStringArray(void *uArray) { | 
1847  | 0  |         delete[] static_cast<UnicodeString *>(uArray);  | 
1848  | 0  |     }  | 
1849  |  | };  | 
1850  |  | // Virtual destructors have to be defined out of line  | 
1851  | 0  | CalendarDataSink::~CalendarDataSink() { | 
1852  | 0  |     arrays.setValueDeleter(deleteUnicodeStringArray);  | 
1853  | 0  | }  | 
1854  |  | }  | 
1855  |  |  | 
1856  |  | //------------------------------------------------------  | 
1857  |  |  | 
1858  |  | static void  | 
1859  | 0  | initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) { | 
1860  | 0  |     if (U_SUCCESS(status)) { | 
1861  | 0  |         length = numStr;  | 
1862  | 0  |         *field = newUnicodeStringArray((size_t)numStr);  | 
1863  | 0  |         if (*field) { | 
1864  | 0  |             for(int32_t i = 0; i<length; i++) { | 
1865  |  |                 // readonly aliases - all "data" strings are constant  | 
1866  |  |                 // -1 as length for variable-length strings (gLastResortDayNames[0] is empty)  | 
1867  | 0  |                 (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1);  | 
1868  | 0  |             }  | 
1869  | 0  |         }  | 
1870  | 0  |         else { | 
1871  | 0  |             length = 0;  | 
1872  | 0  |             status = U_MEMORY_ALLOCATION_ERROR;  | 
1873  | 0  |         }  | 
1874  | 0  |     }  | 
1875  | 0  | }  | 
1876  |  |  | 
1877  |  | static void  | 
1878  | 0  | initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, UErrorCode &status) { | 
1879  | 0  |     if (U_SUCCESS(status)) { | 
1880  | 0  |         UnicodeString keyUString(key.data(), -1, US_INV);  | 
1881  | 0  |         UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString));  | 
1882  |  | 
  | 
1883  | 0  |         if (array != NULL) { | 
1884  | 0  |             length = sink.arraySizes.geti(keyUString);  | 
1885  | 0  |             *field = array;  | 
1886  |  |             // DateFormatSymbols takes ownership of the array:  | 
1887  | 0  |             sink.arrays.remove(keyUString);  | 
1888  | 0  |         } else { | 
1889  | 0  |             length = 0;  | 
1890  | 0  |             status = U_MISSING_RESOURCE_ERROR;  | 
1891  | 0  |         }  | 
1892  | 0  |     }  | 
1893  | 0  | }  | 
1894  |  |  | 
1895  |  | static void  | 
1896  | 0  | initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, int32_t arrayOffset, UErrorCode &status) { | 
1897  | 0  |     if (U_SUCCESS(status)) { | 
1898  | 0  |         UnicodeString keyUString(key.data(), -1, US_INV);  | 
1899  | 0  |         UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString));  | 
1900  |  | 
  | 
1901  | 0  |         if (array != NULL) { | 
1902  | 0  |             int32_t arrayLength = sink.arraySizes.geti(keyUString);  | 
1903  | 0  |             length = arrayLength + arrayOffset;  | 
1904  | 0  |             *field = new UnicodeString[length];  | 
1905  | 0  |             if (*field == NULL) { | 
1906  | 0  |                 status = U_MEMORY_ALLOCATION_ERROR;  | 
1907  | 0  |                 return;  | 
1908  | 0  |             }  | 
1909  | 0  |             uprv_arrayCopy(array, 0, *field, arrayOffset, arrayLength);  | 
1910  | 0  |         } else { | 
1911  | 0  |             length = 0;  | 
1912  | 0  |             status = U_MISSING_RESOURCE_ERROR;  | 
1913  | 0  |         }  | 
1914  | 0  |     }  | 
1915  | 0  | }  | 
1916  |  |  | 
1917  |  | static void  | 
1918  | 0  | initLeapMonthPattern(UnicodeString *field, int32_t index, CalendarDataSink &sink, CharString &path, UErrorCode &status) { | 
1919  | 0  |     field[index].remove();  | 
1920  | 0  |     if (U_SUCCESS(status)) { | 
1921  | 0  |         UnicodeString pathUString(path.data(), -1, US_INV);  | 
1922  | 0  |         Hashtable *leapMonthTable = static_cast<Hashtable*>(sink.maps.get(pathUString));  | 
1923  | 0  |         if (leapMonthTable != NULL) { | 
1924  | 0  |             UnicodeString leapLabel(FALSE, kLeapTagUChar, UPRV_LENGTHOF(kLeapTagUChar));  | 
1925  | 0  |             UnicodeString *leapMonthPattern = static_cast<UnicodeString*>(leapMonthTable->get(leapLabel));  | 
1926  | 0  |             if (leapMonthPattern != NULL) { | 
1927  | 0  |                 field[index].fastCopyFrom(*leapMonthPattern);  | 
1928  | 0  |             } else { | 
1929  | 0  |                 field[index].setToBogus();  | 
1930  | 0  |             }  | 
1931  | 0  |             return;  | 
1932  | 0  |         }  | 
1933  | 0  |         status = U_MISSING_RESOURCE_ERROR;  | 
1934  | 0  |     }  | 
1935  | 0  | }  | 
1936  |  |  | 
1937  |  | static CharString  | 
1938  | 0  | &buildResourcePath(CharString &path, const char* segment1, UErrorCode &errorCode) { | 
1939  | 0  |     return path.clear().append(segment1, -1, errorCode);  | 
1940  | 0  | }  | 
1941  |  |  | 
1942  |  | static CharString  | 
1943  |  | &buildResourcePath(CharString &path, const char* segment1, const char* segment2,  | 
1944  | 0  |                    UErrorCode &errorCode) { | 
1945  | 0  |     return buildResourcePath(path, segment1, errorCode).append('/', errorCode) | 
1946  | 0  |                                                        .append(segment2, -1, errorCode);  | 
1947  | 0  | }  | 
1948  |  |  | 
1949  |  | static CharString  | 
1950  |  | &buildResourcePath(CharString &path, const char* segment1, const char* segment2,  | 
1951  | 0  |                    const char* segment3, UErrorCode &errorCode) { | 
1952  | 0  |     return buildResourcePath(path, segment1, segment2, errorCode).append('/', errorCode) | 
1953  | 0  |                                                                  .append(segment3, -1, errorCode);  | 
1954  | 0  | }  | 
1955  |  |  | 
1956  |  | static CharString  | 
1957  |  | &buildResourcePath(CharString &path, const char* segment1, const char* segment2,  | 
1958  | 0  |                    const char* segment3, const char* segment4, UErrorCode &errorCode) { | 
1959  | 0  |     return buildResourcePath(path, segment1, segment2, segment3, errorCode).append('/', errorCode) | 
1960  | 0  |                                                                            .append(segment4, -1, errorCode);  | 
1961  | 0  | }  | 
1962  |  |  | 
1963  |  | typedef struct { | 
1964  |  |     const char * usageTypeName;  | 
1965  |  |     DateFormatSymbols::ECapitalizationContextUsageType usageTypeEnumValue;  | 
1966  |  | } ContextUsageTypeNameToEnumValue;  | 
1967  |  |  | 
1968  |  | static const ContextUsageTypeNameToEnumValue contextUsageTypeMap[] = { | 
1969  |  |    // Entries must be sorted by usageTypeName; entry with NULL name terminates list.  | 
1970  |  |     { "day-format-except-narrow", DateFormatSymbols::kCapContextUsageDayFormat }, | 
1971  |  |     { "day-narrow",     DateFormatSymbols::kCapContextUsageDayNarrow }, | 
1972  |  |     { "day-standalone-except-narrow", DateFormatSymbols::kCapContextUsageDayStandalone }, | 
1973  |  |     { "era-abbr",       DateFormatSymbols::kCapContextUsageEraAbbrev }, | 
1974  |  |     { "era-name",       DateFormatSymbols::kCapContextUsageEraWide }, | 
1975  |  |     { "era-narrow",     DateFormatSymbols::kCapContextUsageEraNarrow }, | 
1976  |  |     { "metazone-long",  DateFormatSymbols::kCapContextUsageMetazoneLong }, | 
1977  |  |     { "metazone-short", DateFormatSymbols::kCapContextUsageMetazoneShort }, | 
1978  |  |     { "month-format-except-narrow", DateFormatSymbols::kCapContextUsageMonthFormat }, | 
1979  |  |     { "month-narrow",   DateFormatSymbols::kCapContextUsageMonthNarrow }, | 
1980  |  |     { "month-standalone-except-narrow", DateFormatSymbols::kCapContextUsageMonthStandalone }, | 
1981  |  |     { "zone-long",      DateFormatSymbols::kCapContextUsageZoneLong }, | 
1982  |  |     { "zone-short",     DateFormatSymbols::kCapContextUsageZoneShort }, | 
1983  |  |     { NULL, (DateFormatSymbols::ECapitalizationContextUsageType)0 }, | 
1984  |  | };  | 
1985  |  |  | 
1986  |  | // Resource keys to look up localized strings for day periods.  | 
1987  |  | // The first one must be midnight and the second must be noon, so that their indices coincide  | 
1988  |  | // with the am/pm field. Formatting and parsing code for day periods relies on this coincidence.  | 
1989  |  | static const char *dayPeriodKeys[] = {"midnight", "noon", | 
1990  |  |                          "morning1", "afternoon1", "evening1", "night1",  | 
1991  |  |                          "morning2", "afternoon2", "evening2", "night2"};  | 
1992  |  |  | 
1993  |  | UnicodeString* loadDayPeriodStrings(CalendarDataSink &sink, CharString &path,  | 
1994  | 0  |                                     int32_t &stringCount,  UErrorCode &status) { | 
1995  | 0  |     if (U_FAILURE(status)) { return NULL; } | 
1996  |  |  | 
1997  | 0  |     UnicodeString pathUString(path.data(), -1, US_INV);  | 
1998  | 0  |     Hashtable* map = static_cast<Hashtable*>(sink.maps.get(pathUString));  | 
1999  |  | 
  | 
2000  | 0  |     stringCount = UPRV_LENGTHOF(dayPeriodKeys);  | 
2001  | 0  |     UnicodeString *strings = new UnicodeString[stringCount];  | 
2002  | 0  |     if (strings == NULL) { | 
2003  | 0  |         status = U_MEMORY_ALLOCATION_ERROR;  | 
2004  | 0  |         return NULL;  | 
2005  | 0  |     }  | 
2006  |  |  | 
2007  | 0  |     if (map != NULL) { | 
2008  | 0  |         for (int32_t i = 0; i < stringCount; ++i) { | 
2009  | 0  |             UnicodeString dayPeriodKey(dayPeriodKeys[i], -1, US_INV);  | 
2010  | 0  |             UnicodeString *dayPeriod = static_cast<UnicodeString*>(map->get(dayPeriodKey));  | 
2011  | 0  |             if (dayPeriod != NULL) { | 
2012  | 0  |                 strings[i].fastCopyFrom(*dayPeriod);  | 
2013  | 0  |             } else { | 
2014  | 0  |                 strings[i].setToBogus();  | 
2015  | 0  |             }  | 
2016  | 0  |         }  | 
2017  | 0  |     } else { | 
2018  | 0  |         for (int32_t i = 0; i < stringCount; i++) { | 
2019  | 0  |             strings[i].setToBogus();  | 
2020  | 0  |         }  | 
2021  | 0  |     }  | 
2022  | 0  |     return strings;  | 
2023  | 0  | }  | 
2024  |  |  | 
2025  |  |  | 
2026  |  | void  | 
2027  |  | DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData)  | 
2028  | 0  | { | 
2029  | 0  |     int32_t len = 0;  | 
2030  |  |     /* In case something goes wrong, initialize all of the data to NULL. */  | 
2031  | 0  |     fEras = NULL;  | 
2032  | 0  |     fErasCount = 0;  | 
2033  | 0  |     fEraNames = NULL;  | 
2034  | 0  |     fEraNamesCount = 0;  | 
2035  | 0  |     fNarrowEras = NULL;  | 
2036  | 0  |     fNarrowErasCount = 0;  | 
2037  | 0  |     fMonths = NULL;  | 
2038  | 0  |     fMonthsCount=0;  | 
2039  | 0  |     fShortMonths = NULL;  | 
2040  | 0  |     fShortMonthsCount=0;  | 
2041  | 0  |     fNarrowMonths = NULL;  | 
2042  | 0  |     fNarrowMonthsCount=0;  | 
2043  | 0  |     fStandaloneMonths = NULL;  | 
2044  | 0  |     fStandaloneMonthsCount=0;  | 
2045  | 0  |     fStandaloneShortMonths = NULL;  | 
2046  | 0  |     fStandaloneShortMonthsCount=0;  | 
2047  | 0  |     fStandaloneNarrowMonths = NULL;  | 
2048  | 0  |     fStandaloneNarrowMonthsCount=0;  | 
2049  | 0  |     fWeekdays = NULL;  | 
2050  | 0  |     fWeekdaysCount=0;  | 
2051  | 0  |     fShortWeekdays = NULL;  | 
2052  | 0  |     fShortWeekdaysCount=0;  | 
2053  | 0  |     fShorterWeekdays = NULL;  | 
2054  | 0  |     fShorterWeekdaysCount=0;  | 
2055  | 0  |     fNarrowWeekdays = NULL;  | 
2056  | 0  |     fNarrowWeekdaysCount=0;  | 
2057  | 0  |     fStandaloneWeekdays = NULL;  | 
2058  | 0  |     fStandaloneWeekdaysCount=0;  | 
2059  | 0  |     fStandaloneShortWeekdays = NULL;  | 
2060  | 0  |     fStandaloneShortWeekdaysCount=0;  | 
2061  | 0  |     fStandaloneShorterWeekdays = NULL;  | 
2062  | 0  |     fStandaloneShorterWeekdaysCount=0;  | 
2063  | 0  |     fStandaloneNarrowWeekdays = NULL;  | 
2064  | 0  |     fStandaloneNarrowWeekdaysCount=0;  | 
2065  | 0  |     fAmPms = NULL;  | 
2066  | 0  |     fAmPmsCount=0;  | 
2067  | 0  |     fNarrowAmPms = NULL;  | 
2068  | 0  |     fNarrowAmPmsCount=0;  | 
2069  | 0  |     fTimeSeparator.setToBogus();  | 
2070  | 0  |     fQuarters = NULL;  | 
2071  | 0  |     fQuartersCount = 0;  | 
2072  | 0  |     fShortQuarters = NULL;  | 
2073  | 0  |     fShortQuartersCount = 0;  | 
2074  | 0  |     fNarrowQuarters = NULL;  | 
2075  | 0  |     fNarrowQuartersCount = 0;  | 
2076  | 0  |     fStandaloneQuarters = NULL;  | 
2077  | 0  |     fStandaloneQuartersCount = 0;  | 
2078  | 0  |     fStandaloneShortQuarters = NULL;  | 
2079  | 0  |     fStandaloneShortQuartersCount = 0;  | 
2080  | 0  |     fStandaloneNarrowQuarters = NULL;  | 
2081  | 0  |     fStandaloneNarrowQuartersCount = 0;  | 
2082  | 0  |     fLeapMonthPatterns = NULL;  | 
2083  | 0  |     fLeapMonthPatternsCount = 0;  | 
2084  | 0  |     fShortYearNames = NULL;  | 
2085  | 0  |     fShortYearNamesCount = 0;  | 
2086  | 0  |     fShortZodiacNames = NULL;  | 
2087  | 0  |     fShortZodiacNamesCount = 0;  | 
2088  | 0  |     fZoneStringsRowCount = 0;  | 
2089  | 0  |     fZoneStringsColCount = 0;  | 
2090  | 0  |     fZoneStrings = NULL;  | 
2091  | 0  |     fLocaleZoneStrings = NULL;  | 
2092  | 0  |     fAbbreviatedDayPeriods = NULL;  | 
2093  | 0  |     fAbbreviatedDayPeriodsCount = 0;  | 
2094  | 0  |     fWideDayPeriods = NULL;  | 
2095  | 0  |     fWideDayPeriodsCount = 0;  | 
2096  | 0  |     fNarrowDayPeriods = NULL;  | 
2097  | 0  |     fNarrowDayPeriodsCount = 0;  | 
2098  | 0  |     fStandaloneAbbreviatedDayPeriods = NULL;  | 
2099  | 0  |     fStandaloneAbbreviatedDayPeriodsCount = 0;  | 
2100  | 0  |     fStandaloneWideDayPeriods = NULL;  | 
2101  | 0  |     fStandaloneWideDayPeriodsCount = 0;  | 
2102  | 0  |     fStandaloneNarrowDayPeriods = NULL;  | 
2103  | 0  |     fStandaloneNarrowDayPeriodsCount = 0;  | 
2104  | 0  |     uprv_memset(fCapitalization, 0, sizeof(fCapitalization));  | 
2105  |  |  | 
2106  |  |     // We need to preserve the requested locale for  | 
2107  |  |     // lazy ZoneStringFormat instantiation.  ZoneStringFormat  | 
2108  |  |     // is region sensitive, thus, bundle locale bundle's locale  | 
2109  |  |     // is not sufficient.  | 
2110  | 0  |     fZSFLocale = locale;  | 
2111  |  | 
  | 
2112  | 0  |     if (U_FAILURE(status)) return;  | 
2113  |  |  | 
2114  |  |     // Create a CalendarDataSink to process this data and the resource bundles  | 
2115  | 0  |     CalendarDataSink calendarSink(status);  | 
2116  | 0  |     UResourceBundle *rb = ures_open(NULL, locale.getBaseName(), &status);  | 
2117  | 0  |     UResourceBundle *cb = ures_getByKey(rb, gCalendarTag, NULL, &status);  | 
2118  |  | 
  | 
2119  | 0  |     if (U_FAILURE(status)) return;  | 
2120  |  |  | 
2121  |  |     // Iterate over the resource bundle data following the fallbacks through different calendar types  | 
2122  | 0  |     UnicodeString calendarType((type != NULL && *type != '\0')? type : gGregorianTag, -1, US_INV);  | 
2123  | 0  |     while (!calendarType.isBogus()) { | 
2124  | 0  |         CharString calendarTypeBuffer;  | 
2125  | 0  |         calendarTypeBuffer.appendInvariantChars(calendarType, status);  | 
2126  | 0  |         if (U_FAILURE(status)) { return; } | 
2127  | 0  |         const char *calendarTypeCArray = calendarTypeBuffer.data();  | 
2128  |  |  | 
2129  |  |         // Enumerate this calendar type. If the calendar is not found fallback to gregorian  | 
2130  | 0  |         UErrorCode oldStatus = status;  | 
2131  | 0  |         UResourceBundle *ctb = ures_getByKeyWithFallback(cb, calendarTypeCArray, NULL, &status);  | 
2132  | 0  |         if (status == U_MISSING_RESOURCE_ERROR) { | 
2133  | 0  |             ures_close(ctb);  | 
2134  | 0  |             if (uprv_strcmp(calendarTypeCArray, gGregorianTag) != 0) { | 
2135  | 0  |                 calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar));  | 
2136  | 0  |                 calendarSink.visitAllResources();  | 
2137  | 0  |                 status = oldStatus;  | 
2138  | 0  |                 continue;  | 
2139  | 0  |             }  | 
2140  | 0  |             return;  | 
2141  | 0  |         }  | 
2142  |  |  | 
2143  | 0  |         calendarSink.preEnumerate(calendarType);  | 
2144  | 0  |         ures_getAllItemsWithFallback(ctb, "", calendarSink, status);  | 
2145  | 0  |         ures_close(ctb);  | 
2146  | 0  |         if (U_FAILURE(status)) break;  | 
2147  |  |  | 
2148  |  |         // Stop loading when gregorian was loaded  | 
2149  | 0  |         if (uprv_strcmp(calendarTypeCArray, gGregorianTag) == 0) { | 
2150  | 0  |             break;  | 
2151  | 0  |         }  | 
2152  |  |  | 
2153  |  |         // Get the next calendar type to process from the sink  | 
2154  | 0  |         calendarType = calendarSink.nextCalendarType;  | 
2155  |  |  | 
2156  |  |         // Gregorian is always the last fallback  | 
2157  | 0  |         if (calendarType.isBogus()) { | 
2158  | 0  |             calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar));  | 
2159  | 0  |             calendarSink.visitAllResources();  | 
2160  | 0  |         }  | 
2161  | 0  |     }  | 
2162  |  |  | 
2163  |  |     // CharString object to build paths  | 
2164  | 0  |     CharString path;  | 
2165  |  |  | 
2166  |  |     // Load Leap Month Patterns  | 
2167  | 0  |     UErrorCode tempStatus = status;  | 
2168  | 0  |     fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount);  | 
2169  | 0  |     if (fLeapMonthPatterns) { | 
2170  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calendarSink,  | 
2171  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesWideTag, tempStatus), tempStatus);  | 
2172  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calendarSink,  | 
2173  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);  | 
2174  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calendarSink,  | 
2175  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesNarrowTag, tempStatus), tempStatus);  | 
2176  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calendarSink,  | 
2177  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus);  | 
2178  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calendarSink,  | 
2179  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus);  | 
2180  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calendarSink,  | 
2181  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus);  | 
2182  | 0  |         initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calendarSink,  | 
2183  | 0  |                              buildResourcePath(path, gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus);  | 
2184  | 0  |         if (U_SUCCESS(tempStatus)) { | 
2185  |  |             // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't.  | 
2186  |  |             // The ordering of the following statements is important.  | 
2187  | 0  |             if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) { | 
2188  | 0  |                 fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);  | 
2189  | 0  |             }  | 
2190  | 0  |             if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) { | 
2191  | 0  |                 fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]);  | 
2192  | 0  |             }  | 
2193  | 0  |             if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) { | 
2194  | 0  |                 fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);  | 
2195  | 0  |             }  | 
2196  | 0  |             if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) { | 
2197  | 0  |                 fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]);  | 
2198  | 0  |             }  | 
2199  |  |             // end of hack  | 
2200  | 0  |             fLeapMonthPatternsCount = kMonthPatternsCount;  | 
2201  | 0  |         } else { | 
2202  | 0  |             delete[] fLeapMonthPatterns;  | 
2203  | 0  |             fLeapMonthPatterns = NULL;  | 
2204  | 0  |         }  | 
2205  | 0  |     }  | 
2206  |  |  | 
2207  |  |     // Load cyclic names sets  | 
2208  | 0  |     tempStatus = status;  | 
2209  | 0  |     initField(&fShortYearNames, fShortYearNamesCount, calendarSink,  | 
2210  | 0  |               buildResourcePath(path, gCyclicNameSetsTag, gNameSetYearsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);  | 
2211  | 0  |     initField(&fShortZodiacNames, fShortZodiacNamesCount, calendarSink,  | 
2212  | 0  |               buildResourcePath(path, gCyclicNameSetsTag, gNameSetZodiacsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);  | 
2213  |  |  | 
2214  |  |     // Load context transforms and capitalization  | 
2215  | 0  |     tempStatus = U_ZERO_ERROR;  | 
2216  | 0  |     UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus);  | 
2217  | 0  |     if (U_SUCCESS(tempStatus)) { | 
2218  | 0  |         UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, gContextTransformsTag, NULL, &tempStatus);  | 
2219  | 0  |         if (U_SUCCESS(tempStatus)) { | 
2220  | 0  |             UResourceBundle *contextTransformUsage;  | 
2221  | 0  |             while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &tempStatus)) != NULL ) { | 
2222  | 0  |                 const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);  | 
2223  | 0  |                 if (U_SUCCESS(tempStatus) && intVector != NULL && len >= 2) { | 
2224  | 0  |                     const char* usageType = ures_getKey(contextTransformUsage);  | 
2225  | 0  |                     if (usageType != NULL) { | 
2226  | 0  |                         const ContextUsageTypeNameToEnumValue * typeMapPtr = contextUsageTypeMap;  | 
2227  | 0  |                         int32_t compResult = 0;  | 
2228  |  |                         // linear search; list is short and we cannot be sure that bsearch is available  | 
2229  | 0  |                         while ( typeMapPtr->usageTypeName != NULL && (compResult = uprv_strcmp(usageType, typeMapPtr->usageTypeName)) > 0 ) { | 
2230  | 0  |                             ++typeMapPtr;  | 
2231  | 0  |                         }  | 
2232  | 0  |                         if (typeMapPtr->usageTypeName != NULL && compResult == 0) { | 
2233  | 0  |                             fCapitalization[typeMapPtr->usageTypeEnumValue][0] = static_cast<UBool>(intVector[0]);  | 
2234  | 0  |                             fCapitalization[typeMapPtr->usageTypeEnumValue][1] = static_cast<UBool>(intVector[1]);  | 
2235  | 0  |                         }  | 
2236  | 0  |                     }  | 
2237  | 0  |                 }  | 
2238  | 0  |                 tempStatus = U_ZERO_ERROR;  | 
2239  | 0  |                 ures_close(contextTransformUsage);  | 
2240  | 0  |             }  | 
2241  | 0  |             ures_close(contextTransforms);  | 
2242  | 0  |         }  | 
2243  |  | 
  | 
2244  | 0  |         tempStatus = U_ZERO_ERROR;  | 
2245  | 0  |         const LocalPointer<NumberingSystem> numberingSystem(  | 
2246  | 0  |                 NumberingSystem::createInstance(locale, tempStatus), tempStatus);  | 
2247  | 0  |         if (U_SUCCESS(tempStatus)) { | 
2248  |  |             // These functions all fail gracefully if passed NULL pointers and  | 
2249  |  |             // do nothing unless U_SUCCESS(tempStatus), so it's only necessary  | 
2250  |  |             // to check for errors once after all calls are made.  | 
2251  | 0  |             const LocalUResourceBundlePointer numberElementsData(ures_getByKeyWithFallback(  | 
2252  | 0  |                     localeBundle, gNumberElementsTag, NULL, &tempStatus));  | 
2253  | 0  |             const LocalUResourceBundlePointer nsNameData(ures_getByKeyWithFallback(  | 
2254  | 0  |                     numberElementsData.getAlias(), numberingSystem->getName(), NULL, &tempStatus));  | 
2255  | 0  |             const LocalUResourceBundlePointer symbolsData(ures_getByKeyWithFallback(  | 
2256  | 0  |                     nsNameData.getAlias(), gSymbolsTag, NULL, &tempStatus));  | 
2257  | 0  |             fTimeSeparator = ures_getUnicodeStringByKey(  | 
2258  | 0  |                     symbolsData.getAlias(), gTimeSeparatorTag, &tempStatus);  | 
2259  | 0  |             if (U_FAILURE(tempStatus)) { | 
2260  | 0  |                 fTimeSeparator.setToBogus();  | 
2261  | 0  |             }  | 
2262  | 0  |         }  | 
2263  |  | 
  | 
2264  | 0  |         ures_close(localeBundle);  | 
2265  | 0  |     }  | 
2266  |  | 
  | 
2267  | 0  |     if (fTimeSeparator.isBogus()) { | 
2268  | 0  |         fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR);  | 
2269  | 0  |     }  | 
2270  |  |  | 
2271  |  |     // Load day periods  | 
2272  | 0  |     fWideDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2273  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesWideTag, status),  | 
2274  | 0  |                             fWideDayPeriodsCount, status);  | 
2275  | 0  |     fNarrowDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2276  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesNarrowTag, status),  | 
2277  | 0  |                             fNarrowDayPeriodsCount, status);  | 
2278  | 0  |     fAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2279  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesAbbrTag, status),  | 
2280  | 0  |                             fAbbreviatedDayPeriodsCount, status);  | 
2281  | 0  |     fStandaloneWideDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2282  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesWideTag, status),  | 
2283  | 0  |                             fStandaloneWideDayPeriodsCount, status);  | 
2284  | 0  |     fStandaloneNarrowDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2285  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesNarrowTag, status),  | 
2286  | 0  |                             fStandaloneNarrowDayPeriodsCount, status);  | 
2287  | 0  |     fStandaloneAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink,  | 
2288  | 0  |                             buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesAbbrTag, status),  | 
2289  | 0  |                             fStandaloneAbbreviatedDayPeriodsCount, status);  | 
2290  |  | 
  | 
2291  | 0  |     U_LOCALE_BASED(locBased, *this);  | 
2292  |  |     // if we make it to here, the resource data is cool, and we can get everything out  | 
2293  |  |     // of it that we need except for the time-zone and localized-pattern data, which  | 
2294  |  |     // are stored in a separate file  | 
2295  | 0  |     locBased.setLocaleIDs(ures_getLocaleByType(cb, ULOC_VALID_LOCALE, &status),  | 
2296  | 0  |                           ures_getLocaleByType(cb, ULOC_ACTUAL_LOCALE, &status));  | 
2297  |  |  | 
2298  |  |     // Load eras  | 
2299  | 0  |     initField(&fEras, fErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesAbbrTag, status), status);  | 
2300  | 0  |     UErrorCode oldStatus = status;  | 
2301  | 0  |     initField(&fEraNames, fEraNamesCount, calendarSink, buildResourcePath(path, gErasTag, gNamesWideTag, status), status);  | 
2302  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3 | 
2303  | 0  |         status = oldStatus;  | 
2304  | 0  |         assignArray(fEraNames, fEraNamesCount, fEras, fErasCount);  | 
2305  | 0  |     }  | 
2306  |  |     // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too  | 
2307  | 0  |     oldStatus = status;  | 
2308  | 0  |     initField(&fNarrowEras, fNarrowErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesNarrowTag, status), status);  | 
2309  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3 | 
2310  | 0  |         status = oldStatus;  | 
2311  | 0  |         assignArray(fNarrowEras, fNarrowErasCount, fEras, fErasCount);  | 
2312  | 0  |     }  | 
2313  |  |  | 
2314  |  |     // Load month names  | 
2315  | 0  |     initField(&fMonths, fMonthsCount, calendarSink,  | 
2316  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesWideTag, status), status);  | 
2317  | 0  |     initField(&fShortMonths, fShortMonthsCount, calendarSink,  | 
2318  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesAbbrTag, status), status);  | 
2319  | 0  |     initField(&fStandaloneMonths, fStandaloneMonthsCount, calendarSink,  | 
2320  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status);  | 
2321  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide not available, use format/wide */ | 
2322  | 0  |         status = U_ZERO_ERROR;  | 
2323  | 0  |         assignArray(fStandaloneMonths, fStandaloneMonthsCount, fMonths, fMonthsCount);  | 
2324  | 0  |     }  | 
2325  | 0  |     initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calendarSink,  | 
2326  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);  | 
2327  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated not available, use format/abbreviated */ | 
2328  | 0  |         status = U_ZERO_ERROR;  | 
2329  | 0  |         assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, fShortMonths, fShortMonthsCount);  | 
2330  | 0  |     }  | 
2331  |  | 
  | 
2332  | 0  |     UErrorCode narrowMonthsEC = status;  | 
2333  | 0  |     UErrorCode standaloneNarrowMonthsEC = status;  | 
2334  | 0  |     initField(&fNarrowMonths, fNarrowMonthsCount, calendarSink,  | 
2335  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesNarrowTag, narrowMonthsEC), narrowMonthsEC);  | 
2336  | 0  |     initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calendarSink,  | 
2337  | 0  |               buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, narrowMonthsEC), standaloneNarrowMonthsEC);  | 
2338  | 0  |     if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC != U_MISSING_RESOURCE_ERROR) { | 
2339  |  |         // If format/narrow not available, use standalone/narrow  | 
2340  | 0  |         assignArray(fNarrowMonths, fNarrowMonthsCount, fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount);  | 
2341  | 0  |     } else if (narrowMonthsEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) { | 
2342  |  |         // If standalone/narrow not available, use format/narrow  | 
2343  | 0  |         assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fNarrowMonths, fNarrowMonthsCount);  | 
2344  | 0  |     } else if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) { | 
2345  |  |         // If neither is available, use format/abbreviated  | 
2346  | 0  |         assignArray(fNarrowMonths, fNarrowMonthsCount, fShortMonths, fShortMonthsCount);  | 
2347  | 0  |         assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fShortMonths, fShortMonthsCount);  | 
2348  | 0  |     }  | 
2349  |  |  | 
2350  |  |     // Load AM/PM markers; if wide or narrow not available, use short  | 
2351  | 0  |     UErrorCode ampmStatus = U_ZERO_ERROR;  | 
2352  | 0  |     initField(&fAmPms, fAmPmsCount, calendarSink,  | 
2353  | 0  |               buildResourcePath(path, gAmPmMarkersTag, ampmStatus), ampmStatus);  | 
2354  | 0  |     if (U_FAILURE(ampmStatus)) { | 
2355  | 0  |         initField(&fAmPms, fAmPmsCount, calendarSink,  | 
2356  | 0  |                   buildResourcePath(path, gAmPmMarkersAbbrTag, status), status);  | 
2357  | 0  |     }  | 
2358  | 0  |     ampmStatus = U_ZERO_ERROR;  | 
2359  | 0  |     initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink,  | 
2360  | 0  |               buildResourcePath(path, gAmPmMarkersNarrowTag, ampmStatus), ampmStatus);  | 
2361  | 0  |     if (U_FAILURE(ampmStatus)) { | 
2362  | 0  |         initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink,  | 
2363  | 0  |                   buildResourcePath(path, gAmPmMarkersAbbrTag, status), status);  | 
2364  | 0  |     }  | 
2365  |  |  | 
2366  |  |     // Load quarters  | 
2367  | 0  |     initField(&fQuarters, fQuartersCount, calendarSink,  | 
2368  | 0  |               buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesWideTag, status), status);  | 
2369  | 0  |     initField(&fShortQuarters, fShortQuartersCount, calendarSink,  | 
2370  | 0  |               buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesAbbrTag, status), status);  | 
2371  |  | 
  | 
2372  | 0  |     initField(&fStandaloneQuarters, fStandaloneQuartersCount, calendarSink,  | 
2373  | 0  |               buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status);  | 
2374  | 0  |     if(status == U_MISSING_RESOURCE_ERROR) { | 
2375  | 0  |         status = U_ZERO_ERROR;  | 
2376  | 0  |         assignArray(fStandaloneQuarters, fStandaloneQuartersCount, fQuarters, fQuartersCount);  | 
2377  | 0  |     }  | 
2378  | 0  |     initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calendarSink,  | 
2379  | 0  |               buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);  | 
2380  | 0  |     if(status == U_MISSING_RESOURCE_ERROR) { | 
2381  | 0  |         status = U_ZERO_ERROR;  | 
2382  | 0  |         assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, fShortQuarters, fShortQuartersCount);  | 
2383  | 0  |     }  | 
2384  |  |  | 
2385  |  |     // unlike the fields above, narrow format quarters fall back on narrow standalone quarters  | 
2386  | 0  |     initField(&fStandaloneNarrowQuarters, fStandaloneNarrowQuartersCount, calendarSink,  | 
2387  | 0  |               buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);  | 
2388  | 0  |     initField(&fNarrowQuarters, fNarrowQuartersCount, calendarSink,  | 
2389  | 0  |               buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesNarrowTag, status), status);  | 
2390  | 0  |     if(status == U_MISSING_RESOURCE_ERROR) { | 
2391  | 0  |         status = U_ZERO_ERROR;  | 
2392  | 0  |         assignArray(fNarrowQuarters, fNarrowQuartersCount, fStandaloneNarrowQuarters, fStandaloneNarrowQuartersCount);  | 
2393  | 0  |     }  | 
2394  |  |       | 
2395  |  |     // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597)  | 
2396  |  |     /*  | 
2397  |  |     // fastCopyFrom()/setTo() - see assignArray comments  | 
2398  |  |     resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status);  | 
2399  |  |     fLocalPatternChars.setTo(TRUE, resStr, len);  | 
2400  |  |     // If the locale data does not include new pattern chars, use the defaults  | 
2401  |  |     // TODO: Consider making this an error, since this may add conflicting characters.  | 
2402  |  |     if (len < PATTERN_CHARS_LEN) { | 
2403  |  |         fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));  | 
2404  |  |     }  | 
2405  |  |     */  | 
2406  | 0  |     fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);  | 
2407  |  |  | 
2408  |  |     // Format wide weekdays -> fWeekdays  | 
2409  |  |     // {sfb} fixed to handle 1-based weekdays | 
2410  | 0  |     initField(&fWeekdays, fWeekdaysCount, calendarSink,  | 
2411  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesWideTag, status), 1, status);  | 
2412  |  |  | 
2413  |  |     // Format abbreviated weekdays -> fShortWeekdays  | 
2414  | 0  |     initField(&fShortWeekdays, fShortWeekdaysCount, calendarSink,  | 
2415  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesAbbrTag, status), 1, status);  | 
2416  |  |  | 
2417  |  |     // Format short weekdays -> fShorterWeekdays (fall back to abbreviated)  | 
2418  | 0  |     initField(&fShorterWeekdays, fShorterWeekdaysCount, calendarSink,  | 
2419  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesShortTag, status), 1, status);  | 
2420  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { | 
2421  | 0  |         status = U_ZERO_ERROR;  | 
2422  | 0  |         assignArray(fShorterWeekdays, fShorterWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);  | 
2423  | 0  |     }  | 
2424  |  |  | 
2425  |  |     // Stand-alone wide weekdays -> fStandaloneWeekdays  | 
2426  | 0  |     initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, calendarSink,  | 
2427  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status), 1, status);  | 
2428  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide is not available, use format/wide */ | 
2429  | 0  |         status = U_ZERO_ERROR;  | 
2430  | 0  |         assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, fWeekdays, fWeekdaysCount);  | 
2431  | 0  |     }  | 
2432  |  |  | 
2433  |  |     // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays  | 
2434  | 0  |     initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, calendarSink,  | 
2435  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), 1, status);  | 
2436  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated is not available, use format/abbreviated */ | 
2437  | 0  |         status = U_ZERO_ERROR;  | 
2438  | 0  |         assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);  | 
2439  | 0  |     }  | 
2440  |  |  | 
2441  |  |     // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated)  | 
2442  | 0  |     initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, calendarSink,  | 
2443  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status), 1, status);  | 
2444  | 0  |     if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/short is not available, use format/short */ | 
2445  | 0  |         status = U_ZERO_ERROR;  | 
2446  | 0  |         assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, fShorterWeekdays, fShorterWeekdaysCount);  | 
2447  | 0  |     }  | 
2448  |  |  | 
2449  |  |     // Format narrow weekdays -> fNarrowWeekdays  | 
2450  | 0  |     UErrorCode narrowWeeksEC = status;  | 
2451  | 0  |     initField(&fNarrowWeekdays, fNarrowWeekdaysCount, calendarSink,  | 
2452  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesNarrowTag, status), 1, narrowWeeksEC);  | 
2453  |  |     // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays  | 
2454  | 0  |     UErrorCode standaloneNarrowWeeksEC = status;  | 
2455  | 0  |     initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, calendarSink,  | 
2456  | 0  |               buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), 1, standaloneNarrowWeeksEC);  | 
2457  |  | 
  | 
2458  | 0  |     if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC != U_MISSING_RESOURCE_ERROR) { | 
2459  |  |         // If format/narrow not available, use standalone/narrow  | 
2460  | 0  |         assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount);  | 
2461  | 0  |     } else if (narrowWeeksEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR) { | 
2462  |  |         // If standalone/narrow not available, use format/narrow  | 
2463  | 0  |         assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fNarrowWeekdays, fNarrowWeekdaysCount);  | 
2464  | 0  |     } else if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR ) { | 
2465  |  |         // If neither is available, use format/abbreviated  | 
2466  | 0  |         assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);  | 
2467  | 0  |         assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);  | 
2468  | 0  |     }  | 
2469  |  |  | 
2470  |  |     // Last resort fallback in case previous data wasn't loaded  | 
2471  | 0  |     if (U_FAILURE(status))  | 
2472  | 0  |     { | 
2473  | 0  |         if (useLastResortData)  | 
2474  | 0  |         { | 
2475  |  |             // Handle the case in which there is no resource data present.  | 
2476  |  |             // We don't have to generate usable patterns in this situation;  | 
2477  |  |             // we just need to produce something that will be semi-intelligible  | 
2478  |  |             // in most locales.  | 
2479  |  | 
  | 
2480  | 0  |             status = U_USING_FALLBACK_WARNING;  | 
2481  |  |             //TODO(fabalbon): make sure we are storing las resort data for all fields in here.  | 
2482  | 0  |             initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);  | 
2483  | 0  |             initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);  | 
2484  | 0  |             initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);  | 
2485  | 0  |             initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);  | 
2486  | 0  |             initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);  | 
2487  | 0  |             initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);  | 
2488  | 0  |             initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);  | 
2489  | 0  |             initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);  | 
2490  | 0  |             initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);  | 
2491  | 0  |             initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2492  | 0  |             initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2493  | 0  |             initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2494  | 0  |             initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2495  | 0  |             initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2496  | 0  |             initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2497  | 0  |             initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2498  | 0  |             initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);  | 
2499  | 0  |             initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);  | 
2500  | 0  |             initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);  | 
2501  | 0  |             initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2502  | 0  |             initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2503  | 0  |             initField(&fNarrowQuarters, fNarrowQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2504  | 0  |             initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2505  | 0  |             initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2506  | 0  |             initField(&fStandaloneNarrowQuarters, fStandaloneNarrowQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);  | 
2507  | 0  |             fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);  | 
2508  | 0  |         }  | 
2509  | 0  |     }  | 
2510  |  |  | 
2511  |  |     // Close resources  | 
2512  | 0  |     ures_close(cb);  | 
2513  | 0  |     ures_close(rb);  | 
2514  | 0  | }  | 
2515  |  |  | 
2516  |  | Locale  | 
2517  | 0  | DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const { | 
2518  | 0  |     U_LOCALE_BASED(locBased, *this);  | 
2519  | 0  |     return locBased.getLocale(type, status);  | 
2520  | 0  | }  | 
2521  |  |  | 
2522  |  | U_NAMESPACE_END  | 
2523  |  |  | 
2524  |  | #endif /* #if !UCONFIG_NO_FORMATTING */  | 
2525  |  |  | 
2526  |  | //eof  |