1 /*
2 *******************************************************************************
3 * Copyright (C) 1997-2015, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
6 *
7 * File DTFMTSYM.CPP
8 *
9 * Modification History:
10 *
11 * Date Name Description
12 * 02/19/97 aliu Converted from java.
13 * 07/21/98 stephen Added getZoneIndex
14 * Changed weekdays/short weekdays to be one-based
15 * 06/14/99 stephen Removed SimpleDateFormat::fgTimeZoneDataSuffix
16 * 11/16/99 weiv Added 'Y' and 'e' to fgPatternChars
17 * 03/27/00 weiv Keeping resource bundle around!
18 * 06/30/05 emmons Added eraNames, narrow month/day, standalone context
19 * 10/12/05 emmons Added setters for eraNames, month/day by width/context
20 *******************************************************************************
21 */
22 #include "unicode/utypes.h"
23
24 #if !UCONFIG_NO_FORMATTING
25 #include "unicode/ustring.h"
26 #include "unicode/localpointer.h"
27 #include "unicode/dtfmtsym.h"
28 #include "unicode/smpdtfmt.h"
29 #include "unicode/msgfmt.h"
30 #include "unicode/numsys.h"
31 #include "unicode/tznames.h"
32 #include "cpputils.h"
33 #include "umutex.h"
34 #include "cmemory.h"
35 #include "cstring.h"
36 #include "locbased.h"
37 #include "gregoimp.h"
38 #include "hash.h"
39 #include "uresimp.h"
40 #include "ureslocs.h"
41 #include "shareddateformatsymbols.h"
42 #include "unicode/calendar.h"
43 #include "unifiedcache.h"
44
45 // *****************************************************************************
46 // class DateFormatSymbols
47 // *****************************************************************************
48
49 /**
50 * These are static arrays we use only in the case where we have no
51 * resource data.
52 */
53
54 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
55 #define PATTERN_CHARS_LEN 36
56 #else
57 #define PATTERN_CHARS_LEN 35
58 #endif
59
60 /**
61 * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
62 * locales use the same these unlocalized pattern characters.
63 */
64 static const UChar gPatternChars[] = {
65 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
66 // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr:
67 #else
68 // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr
69 #endif
70 0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
71 0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
72 0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0x56,
73 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
74 0x55, 0x4F, 0x58, 0x78, 0x72, 0x3a, 0
75 #else
76 0x55, 0x4F, 0x58, 0x78, 0x72, 0
77 #endif
78 };
79
80 /* length of an array */
81 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
82
83 //------------------------------------------------------
84 // Strings of last resort. These are only used if we have no resource
85 // files. They aren't designed for actual use, just for backup.
86
87 // These are the month names and abbreviations of last resort.
88 static const UChar gLastResortMonthNames[13][3] =
89 {
90 {0x0030, 0x0031, 0x0000}, /* "01" */
91 {0x0030, 0x0032, 0x0000}, /* "02" */
92 {0x0030, 0x0033, 0x0000}, /* "03" */
93 {0x0030, 0x0034, 0x0000}, /* "04" */
94 {0x0030, 0x0035, 0x0000}, /* "05" */
95 {0x0030, 0x0036, 0x0000}, /* "06" */
96 {0x0030, 0x0037, 0x0000}, /* "07" */
97 {0x0030, 0x0038, 0x0000}, /* "08" */
98 {0x0030, 0x0039, 0x0000}, /* "09" */
99 {0x0031, 0x0030, 0x0000}, /* "10" */
100 {0x0031, 0x0031, 0x0000}, /* "11" */
101 {0x0031, 0x0032, 0x0000}, /* "12" */
102 {0x0031, 0x0033, 0x0000} /* "13" */
103 };
104
105 // These are the weekday names and abbreviations of last resort.
106 static const UChar gLastResortDayNames[8][2] =
107 {
108 {0x0030, 0x0000}, /* "0" */
109 {0x0031, 0x0000}, /* "1" */
110 {0x0032, 0x0000}, /* "2" */
111 {0x0033, 0x0000}, /* "3" */
112 {0x0034, 0x0000}, /* "4" */
113 {0x0035, 0x0000}, /* "5" */
114 {0x0036, 0x0000}, /* "6" */
115 {0x0037, 0x0000} /* "7" */
116 };
117
118 // These are the quarter names and abbreviations of last resort.
119 static const UChar gLastResortQuarters[4][2] =
120 {
121 {0x0031, 0x0000}, /* "1" */
122 {0x0032, 0x0000}, /* "2" */
123 {0x0033, 0x0000}, /* "3" */
124 {0x0034, 0x0000}, /* "4" */
125 };
126
127 // These are the am/pm and BC/AD markers of last resort.
128 static const UChar gLastResortAmPmMarkers[2][3] =
129 {
130 {0x0041, 0x004D, 0x0000}, /* "AM" */
131 {0x0050, 0x004D, 0x0000} /* "PM" */
132 };
133
134 static const UChar gLastResortEras[2][3] =
135 {
136 {0x0042, 0x0043, 0x0000}, /* "BC" */
137 {0x0041, 0x0044, 0x0000} /* "AD" */
138 };
139
140 /* Sizes for the last resort string arrays */
141 typedef enum LastResortSize {
142 kMonthNum = 13,
143 kMonthLen = 3,
144
145 kDayNum = 8,
146 kDayLen = 2,
147
148 kAmPmNum = 2,
149 kAmPmLen = 3,
150
151 kQuarterNum = 4,
152 kQuarterLen = 2,
153
154 kEraNum = 2,
155 kEraLen = 3,
156
157 kZoneNum = 5,
158 kZoneLen = 4,
159
160 kGmtHourNum = 4,
161 kGmtHourLen = 10
162 } LastResortSize;
163
164 U_NAMESPACE_BEGIN
165
~SharedDateFormatSymbols()166 SharedDateFormatSymbols::~SharedDateFormatSymbols() {
167 }
168
169 template<> U_I18N_API
170 const SharedDateFormatSymbols *
createObject(const void *,UErrorCode & status) const171 LocaleCacheKey<SharedDateFormatSymbols>::createObject(
172 const void */*unusedContext*/, UErrorCode &status) const {
173 char type[256];
174 Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status);
175 if (U_FAILURE(status)) {
176 return NULL;
177 }
178 SharedDateFormatSymbols *shared
179 = new SharedDateFormatSymbols(fLoc, type, status);
180 if (shared == NULL) {
181 status = U_MEMORY_ALLOCATION_ERROR;
182 return NULL;
183 }
184 if (U_FAILURE(status)) {
185 delete shared;
186 return NULL;
187 }
188 shared->addRef();
189 return shared;
190 }
191
192 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)
193
194 #define kSUPPLEMENTAL "supplementalData"
195
196 /**
197 * These are the tags we expect to see in normal resource bundle files associated
198 * with a locale and calendar
199 */
200 static const char gErasTag[]="eras";
201 static const char gCyclicNameSetsTag[]="cyclicNameSets";
202 static const char gNameSetYearsTag[]="years";
203 static const char gNameSetZodiacsTag[]="zodiacs";
204 static const char gMonthNamesTag[]="monthNames";
205 static const char gMonthPatternsTag[]="monthPatterns";
206 static const char gDayNamesTag[]="dayNames";
207 static const char gNamesWideTag[]="wide";
208 static const char gNamesAbbrTag[]="abbreviated";
209 static const char gNamesShortTag[]="short";
210 static const char gNamesNarrowTag[]="narrow";
211 static const char gNamesAllTag[]="all";
212 static const char gNamesLeapTag[]="leap";
213 static const char gNamesFormatTag[]="format";
214 static const char gNamesStandaloneTag[]="stand-alone";
215 static const char gNamesNumericTag[]="numeric";
216 static const char gAmPmMarkersTag[]="AmPmMarkers";
217 static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow";
218 static const char gQuartersTag[]="quarters";
219 static const char gNumberElementsTag[]="NumberElements";
220 static const char gSymbolsTag[]="symbols";
221 static const char gTimeSeparatorTag[]="timeSeparator";
222
223 // static const char gZoneStringsTag[]="zoneStrings";
224
225 // static const char gLocalPatternCharsTag[]="localPatternChars";
226
227 static const char gContextTransformsTag[]="contextTransforms";
228
229 static UMutex LOCK = U_MUTEX_INITIALIZER;
230
231 /**
232 * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
233 * Work around this.
234 */
newUnicodeStringArray(size_t count)235 static inline UnicodeString* newUnicodeStringArray(size_t count) {
236 return new UnicodeString[count ? count : 1];
237 }
238
239 //------------------------------------------------------
240
241 DateFormatSymbols * U_EXPORT2
createForLocale(const Locale & locale,UErrorCode & status)242 DateFormatSymbols::createForLocale(
243 const Locale& locale, UErrorCode &status) {
244 const SharedDateFormatSymbols *shared = NULL;
245 UnifiedCache::getByLocale(locale, shared, status);
246 if (U_FAILURE(status)) {
247 return NULL;
248 }
249 DateFormatSymbols *result = new DateFormatSymbols(shared->get());
250 shared->removeRef();
251 if (result == NULL) {
252 status = U_MEMORY_ALLOCATION_ERROR;
253 return NULL;
254 }
255 return result;
256 }
257
DateFormatSymbols(const Locale & locale,UErrorCode & status)258 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
259 UErrorCode& status)
260 : UObject()
261 {
262 initializeData(locale, NULL, status);
263 }
264
DateFormatSymbols(UErrorCode & status)265 DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
266 : UObject()
267 {
268 initializeData(Locale::getDefault(), NULL, status, TRUE);
269 }
270
271
DateFormatSymbols(const Locale & locale,const char * type,UErrorCode & status)272 DateFormatSymbols::DateFormatSymbols(const Locale& locale,
273 const char *type,
274 UErrorCode& status)
275 : UObject()
276 {
277 initializeData(locale, type, status);
278 }
279
DateFormatSymbols(const char * type,UErrorCode & status)280 DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
281 : UObject()
282 {
283 initializeData(Locale::getDefault(), type, status, TRUE);
284 }
285
DateFormatSymbols(const DateFormatSymbols & other)286 DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
287 : UObject(other)
288 {
289 copyData(other);
290 }
291
292 void
assignArray(UnicodeString * & dstArray,int32_t & dstCount,const UnicodeString * srcArray,int32_t srcCount)293 DateFormatSymbols::assignArray(UnicodeString*& dstArray,
294 int32_t& dstCount,
295 const UnicodeString* srcArray,
296 int32_t srcCount)
297 {
298 // assignArray() is only called by copyData(), which in turn implements the
299 // copy constructor and the assignment operator.
300 // All strings in a DateFormatSymbols object are created in one of the following
301 // three ways that all allow to safely use UnicodeString::fastCopyFrom():
302 // - readonly-aliases from resource bundles
303 // - readonly-aliases or allocated strings from constants
304 // - safely cloned strings (with owned buffers) from setXYZ() functions
305 //
306 // Note that this is true for as long as DateFormatSymbols can be constructed
307 // only from a locale bundle or set via the cloning API,
308 // *and* for as long as all the strings are in *private* fields, preventing
309 // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()).
310 dstCount = srcCount;
311 dstArray = newUnicodeStringArray(srcCount);
312 if(dstArray != NULL) {
313 int32_t i;
314 for(i=0; i<srcCount; ++i) {
315 dstArray[i].fastCopyFrom(srcArray[i]);
316 }
317 }
318 }
319
320 /**
321 * Create a copy, in fZoneStrings, of the given zone strings array. The
322 * member variables fZoneStringsRowCount and fZoneStringsColCount should
323 * be set already by the caller.
324 */
325 void
createZoneStrings(const UnicodeString * const * otherStrings)326 DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
327 {
328 int32_t row, col;
329 UBool failed = FALSE;
330
331 fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
332 if (fZoneStrings != NULL) {
333 for (row=0; row<fZoneStringsRowCount; ++row)
334 {
335 fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount);
336 if (fZoneStrings[row] == NULL) {
337 failed = TRUE;
338 break;
339 }
340 for (col=0; col<fZoneStringsColCount; ++col) {
341 // fastCopyFrom() - see assignArray comments
342 fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);
343 }
344 }
345 }
346 // If memory allocation failed, roll back and delete fZoneStrings
347 if (failed) {
348 for (int i = row; i >= 0; i--) {
349 delete[] fZoneStrings[i];
350 }
351 uprv_free(fZoneStrings);
352 fZoneStrings = NULL;
353 }
354 }
355
356 /**
357 * Copy all of the other's data to this.
358 */
359 void
copyData(const DateFormatSymbols & other)360 DateFormatSymbols::copyData(const DateFormatSymbols& other) {
361 UErrorCode status = U_ZERO_ERROR;
362 U_LOCALE_BASED(locBased, *this);
363 locBased.setLocaleIDs(
364 other.getLocale(ULOC_VALID_LOCALE, status),
365 other.getLocale(ULOC_ACTUAL_LOCALE, status));
366 assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
367 assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
368 assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);
369 assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);
370 assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);
371 assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);
372 assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount);
373 assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount);
374 assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount);
375 assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount);
376 assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount);
377 assignArray(fShorterWeekdays, fShorterWeekdaysCount, other.fShorterWeekdays, other.fShorterWeekdaysCount);
378 assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount);
379 assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount);
380 assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount);
381 assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount);
382 assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);
383 assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);
384 assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount );
385 fTimeSeparator.fastCopyFrom(other.fTimeSeparator); // fastCopyFrom() - see assignArray comments
386 assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);
387 assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);
388 assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount);
389 assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount);
390 if (other.fLeapMonthPatterns != NULL) {
391 assignArray(fLeapMonthPatterns, fLeapMonthPatternsCount, other.fLeapMonthPatterns, other.fLeapMonthPatternsCount);
392 } else {
393 fLeapMonthPatterns = NULL;
394 fLeapMonthPatternsCount = 0;
395 }
396 if (other.fShortYearNames != NULL) {
397 assignArray(fShortYearNames, fShortYearNamesCount, other.fShortYearNames, other.fShortYearNamesCount);
398 } else {
399 fShortYearNames = NULL;
400 fShortYearNamesCount = 0;
401 }
402 if (other.fShortZodiacNames != NULL) {
403 assignArray(fShortZodiacNames, fShortZodiacNamesCount, other.fShortZodiacNames, other.fShortZodiacNamesCount);
404 } else {
405 fShortZodiacNames = NULL;
406 fShortZodiacNamesCount = 0;
407 }
408
409 if (other.fZoneStrings != NULL) {
410 fZoneStringsColCount = other.fZoneStringsColCount;
411 fZoneStringsRowCount = other.fZoneStringsRowCount;
412 createZoneStrings((const UnicodeString**)other.fZoneStrings);
413
414 } else {
415 fZoneStrings = NULL;
416 fZoneStringsColCount = 0;
417 fZoneStringsRowCount = 0;
418 }
419 fZSFLocale = other.fZSFLocale;
420 // Other zone strings data is created on demand
421 fLocaleZoneStrings = NULL;
422
423 // fastCopyFrom() - see assignArray comments
424 fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);
425
426 uprv_memcpy(fCapitalization, other.fCapitalization, sizeof(fCapitalization));
427 }
428
429 /**
430 * Assignment operator.
431 */
operator =(const DateFormatSymbols & other)432 DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
433 {
434 dispose();
435 copyData(other);
436
437 return *this;
438 }
439
~DateFormatSymbols()440 DateFormatSymbols::~DateFormatSymbols()
441 {
442 dispose();
443 }
444
dispose()445 void DateFormatSymbols::dispose()
446 {
447 if (fEras) delete[] fEras;
448 if (fEraNames) delete[] fEraNames;
449 if (fNarrowEras) delete[] fNarrowEras;
450 if (fMonths) delete[] fMonths;
451 if (fShortMonths) delete[] fShortMonths;
452 if (fNarrowMonths) delete[] fNarrowMonths;
453 if (fStandaloneMonths) delete[] fStandaloneMonths;
454 if (fStandaloneShortMonths) delete[] fStandaloneShortMonths;
455 if (fStandaloneNarrowMonths) delete[] fStandaloneNarrowMonths;
456 if (fWeekdays) delete[] fWeekdays;
457 if (fShortWeekdays) delete[] fShortWeekdays;
458 if (fShorterWeekdays) delete[] fShorterWeekdays;
459 if (fNarrowWeekdays) delete[] fNarrowWeekdays;
460 if (fStandaloneWeekdays) delete[] fStandaloneWeekdays;
461 if (fStandaloneShortWeekdays) delete[] fStandaloneShortWeekdays;
462 if (fStandaloneShorterWeekdays) delete[] fStandaloneShorterWeekdays;
463 if (fStandaloneNarrowWeekdays) delete[] fStandaloneNarrowWeekdays;
464 if (fAmPms) delete[] fAmPms;
465 if (fNarrowAmPms) delete[] fNarrowAmPms;
466 if (fQuarters) delete[] fQuarters;
467 if (fShortQuarters) delete[] fShortQuarters;
468 if (fStandaloneQuarters) delete[] fStandaloneQuarters;
469 if (fStandaloneShortQuarters) delete[] fStandaloneShortQuarters;
470 if (fLeapMonthPatterns) delete[] fLeapMonthPatterns;
471 if (fShortYearNames) delete[] fShortYearNames;
472 if (fShortZodiacNames) delete[] fShortZodiacNames;
473
474 disposeZoneStrings();
475 }
476
disposeZoneStrings()477 void DateFormatSymbols::disposeZoneStrings()
478 {
479 if (fZoneStrings) {
480 for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
481 delete[] fZoneStrings[row];
482 }
483 uprv_free(fZoneStrings);
484 }
485 if (fLocaleZoneStrings) {
486 for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
487 delete[] fLocaleZoneStrings[row];
488 }
489 uprv_free(fLocaleZoneStrings);
490 }
491
492 fZoneStrings = NULL;
493 fLocaleZoneStrings = NULL;
494 fZoneStringsRowCount = 0;
495 fZoneStringsColCount = 0;
496 }
497
498 UBool
arrayCompare(const UnicodeString * array1,const UnicodeString * array2,int32_t count)499 DateFormatSymbols::arrayCompare(const UnicodeString* array1,
500 const UnicodeString* array2,
501 int32_t count)
502 {
503 if (array1 == array2) return TRUE;
504 while (count>0)
505 {
506 --count;
507 if (array1[count] != array2[count]) return FALSE;
508 }
509 return TRUE;
510 }
511
512 UBool
operator ==(const DateFormatSymbols & other) const513 DateFormatSymbols::operator==(const DateFormatSymbols& other) const
514 {
515 // First do cheap comparisons
516 if (this == &other) {
517 return TRUE;
518 }
519 if (fErasCount == other.fErasCount &&
520 fEraNamesCount == other.fEraNamesCount &&
521 fNarrowErasCount == other.fNarrowErasCount &&
522 fMonthsCount == other.fMonthsCount &&
523 fShortMonthsCount == other.fShortMonthsCount &&
524 fNarrowMonthsCount == other.fNarrowMonthsCount &&
525 fStandaloneMonthsCount == other.fStandaloneMonthsCount &&
526 fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount &&
527 fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount &&
528 fWeekdaysCount == other.fWeekdaysCount &&
529 fShortWeekdaysCount == other.fShortWeekdaysCount &&
530 fShorterWeekdaysCount == other.fShorterWeekdaysCount &&
531 fNarrowWeekdaysCount == other.fNarrowWeekdaysCount &&
532 fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount &&
533 fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount &&
534 fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount &&
535 fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&
536 fAmPmsCount == other.fAmPmsCount &&
537 fNarrowAmPmsCount == other.fNarrowAmPmsCount &&
538 fQuartersCount == other.fQuartersCount &&
539 fShortQuartersCount == other.fShortQuartersCount &&
540 fStandaloneQuartersCount == other.fStandaloneQuartersCount &&
541 fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount &&
542 fLeapMonthPatternsCount == other.fLeapMonthPatternsCount &&
543 fShortYearNamesCount == other.fShortYearNamesCount &&
544 fShortZodiacNamesCount == other.fShortZodiacNamesCount &&
545 (uprv_memcmp(fCapitalization, other.fCapitalization, sizeof(fCapitalization))==0))
546 {
547 // Now compare the arrays themselves
548 if (arrayCompare(fEras, other.fEras, fErasCount) &&
549 arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&
550 arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) &&
551 arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
552 arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
553 arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&
554 arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) &&
555 arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) &&
556 arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) &&
557 arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&
558 arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&
559 arrayCompare(fShorterWeekdays, other.fShorterWeekdays, fShorterWeekdaysCount) &&
560 arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) &&
561 arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) &&
562 arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) &&
563 arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) &&
564 arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&
565 arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&
566 arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) &&
567 fTimeSeparator == other.fTimeSeparator &&
568 arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&
569 arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&
570 arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) &&
571 arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount) &&
572 arrayCompare(fLeapMonthPatterns, other.fLeapMonthPatterns, fLeapMonthPatternsCount) &&
573 arrayCompare(fShortYearNames, other.fShortYearNames, fShortYearNamesCount) &&
574 arrayCompare(fShortZodiacNames, other.fShortZodiacNames, fShortZodiacNamesCount))
575 {
576 // Compare the contents of fZoneStrings
577 if (fZoneStrings == NULL && other.fZoneStrings == NULL) {
578 if (fZSFLocale == other.fZSFLocale) {
579 return TRUE;
580 }
581 } else if (fZoneStrings != NULL && other.fZoneStrings != NULL) {
582 if (fZoneStringsRowCount == other.fZoneStringsRowCount
583 && fZoneStringsColCount == other.fZoneStringsColCount) {
584 UBool cmpres = TRUE;
585 for (int32_t i = 0; (i < fZoneStringsRowCount) && cmpres; i++) {
586 cmpres = arrayCompare(fZoneStrings[i], other.fZoneStrings[i], fZoneStringsColCount);
587 }
588 return cmpres;
589 }
590 }
591 return FALSE;
592 }
593 }
594 return FALSE;
595 }
596
597 //------------------------------------------------------
598
599 const UnicodeString*
getEras(int32_t & count) const600 DateFormatSymbols::getEras(int32_t &count) const
601 {
602 count = fErasCount;
603 return fEras;
604 }
605
606 const UnicodeString*
getEraNames(int32_t & count) const607 DateFormatSymbols::getEraNames(int32_t &count) const
608 {
609 count = fEraNamesCount;
610 return fEraNames;
611 }
612
613 const UnicodeString*
getNarrowEras(int32_t & count) const614 DateFormatSymbols::getNarrowEras(int32_t &count) const
615 {
616 count = fNarrowErasCount;
617 return fNarrowEras;
618 }
619
620 const UnicodeString*
getMonths(int32_t & count) const621 DateFormatSymbols::getMonths(int32_t &count) const
622 {
623 count = fMonthsCount;
624 return fMonths;
625 }
626
627 const UnicodeString*
getShortMonths(int32_t & count) const628 DateFormatSymbols::getShortMonths(int32_t &count) const
629 {
630 count = fShortMonthsCount;
631 return fShortMonths;
632 }
633
634 const UnicodeString*
getMonths(int32_t & count,DtContextType context,DtWidthType width) const635 DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const
636 {
637 UnicodeString *returnValue = NULL;
638
639 switch (context) {
640 case FORMAT :
641 switch(width) {
642 case WIDE :
643 count = fMonthsCount;
644 returnValue = fMonths;
645 break;
646 case ABBREVIATED :
647 case SHORT : // no month data for this, defaults to ABBREVIATED
648 count = fShortMonthsCount;
649 returnValue = fShortMonths;
650 break;
651 case NARROW :
652 count = fNarrowMonthsCount;
653 returnValue = fNarrowMonths;
654 break;
655 case DT_WIDTH_COUNT :
656 break;
657 }
658 break;
659 case STANDALONE :
660 switch(width) {
661 case WIDE :
662 count = fStandaloneMonthsCount;
663 returnValue = fStandaloneMonths;
664 break;
665 case ABBREVIATED :
666 case SHORT : // no month data for this, defaults to ABBREVIATED
667 count = fStandaloneShortMonthsCount;
668 returnValue = fStandaloneShortMonths;
669 break;
670 case NARROW :
671 count = fStandaloneNarrowMonthsCount;
672 returnValue = fStandaloneNarrowMonths;
673 break;
674 case DT_WIDTH_COUNT :
675 break;
676 }
677 break;
678 case DT_CONTEXT_COUNT :
679 break;
680 }
681 return returnValue;
682 }
683
684 const UnicodeString*
getWeekdays(int32_t & count) const685 DateFormatSymbols::getWeekdays(int32_t &count) const
686 {
687 count = fWeekdaysCount;
688 return fWeekdays;
689 }
690
691 const UnicodeString*
getShortWeekdays(int32_t & count) const692 DateFormatSymbols::getShortWeekdays(int32_t &count) const
693 {
694 count = fShortWeekdaysCount;
695 return fShortWeekdays;
696 }
697
698 const UnicodeString*
getWeekdays(int32_t & count,DtContextType context,DtWidthType width) const699 DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const
700 {
701 UnicodeString *returnValue = NULL;
702 switch (context) {
703 case FORMAT :
704 switch(width) {
705 case WIDE :
706 count = fWeekdaysCount;
707 returnValue = fWeekdays;
708 break;
709 case ABBREVIATED :
710 count = fShortWeekdaysCount;
711 returnValue = fShortWeekdays;
712 break;
713 case SHORT :
714 count = fShorterWeekdaysCount;
715 returnValue = fShorterWeekdays;
716 break;
717 case NARROW :
718 count = fNarrowWeekdaysCount;
719 returnValue = fNarrowWeekdays;
720 break;
721 case DT_WIDTH_COUNT :
722 break;
723 }
724 break;
725 case STANDALONE :
726 switch(width) {
727 case WIDE :
728 count = fStandaloneWeekdaysCount;
729 returnValue = fStandaloneWeekdays;
730 break;
731 case ABBREVIATED :
732 count = fStandaloneShortWeekdaysCount;
733 returnValue = fStandaloneShortWeekdays;
734 break;
735 case SHORT :
736 count = fStandaloneShorterWeekdaysCount;
737 returnValue = fStandaloneShorterWeekdays;
738 break;
739 case NARROW :
740 count = fStandaloneNarrowWeekdaysCount;
741 returnValue = fStandaloneNarrowWeekdays;
742 break;
743 case DT_WIDTH_COUNT :
744 break;
745 }
746 break;
747 case DT_CONTEXT_COUNT :
748 break;
749 }
750 return returnValue;
751 }
752
753 const UnicodeString*
getQuarters(int32_t & count,DtContextType context,DtWidthType width) const754 DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const
755 {
756 UnicodeString *returnValue = NULL;
757
758 switch (context) {
759 case FORMAT :
760 switch(width) {
761 case WIDE :
762 count = fQuartersCount;
763 returnValue = fQuarters;
764 break;
765 case ABBREVIATED :
766 case SHORT : // no quarter data for this, defaults to ABBREVIATED
767 count = fShortQuartersCount;
768 returnValue = fShortQuarters;
769 break;
770 case NARROW :
771 count = 0;
772 returnValue = NULL;
773 break;
774 case DT_WIDTH_COUNT :
775 break;
776 }
777 break;
778 case STANDALONE :
779 switch(width) {
780 case WIDE :
781 count = fStandaloneQuartersCount;
782 returnValue = fStandaloneQuarters;
783 break;
784 case ABBREVIATED :
785 case SHORT : // no quarter data for this, defaults to ABBREVIATED
786 count = fStandaloneShortQuartersCount;
787 returnValue = fStandaloneShortQuarters;
788 break;
789 case NARROW :
790 count = 0;
791 returnValue = NULL;
792 break;
793 case DT_WIDTH_COUNT :
794 break;
795 }
796 break;
797 case DT_CONTEXT_COUNT :
798 break;
799 }
800 return returnValue;
801 }
802
803 UnicodeString&
getTimeSeparatorString(UnicodeString & result) const804 DateFormatSymbols::getTimeSeparatorString(UnicodeString& result) const
805 {
806 // fastCopyFrom() - see assignArray comments
807 return result.fastCopyFrom(fTimeSeparator);
808 }
809
810 const UnicodeString*
getAmPmStrings(int32_t & count) const811 DateFormatSymbols::getAmPmStrings(int32_t &count) const
812 {
813 count = fAmPmsCount;
814 return fAmPms;
815 }
816
817 const UnicodeString*
getLeapMonthPatterns(int32_t & count) const818 DateFormatSymbols::getLeapMonthPatterns(int32_t &count) const
819 {
820 count = fLeapMonthPatternsCount;
821 return fLeapMonthPatterns;
822 }
823
824 const UnicodeString*
getYearNames(int32_t & count,DtContextType,DtWidthType) const825 DateFormatSymbols::getYearNames(int32_t& count,
826 DtContextType /*ignored*/, DtWidthType /*ignored*/) const
827 {
828 count = fShortYearNamesCount;
829 return fShortYearNames;
830 }
831
832 void
setYearNames(const UnicodeString * yearNames,int32_t count,DtContextType context,DtWidthType width)833 DateFormatSymbols::setYearNames(const UnicodeString* yearNames, int32_t count,
834 DtContextType context, DtWidthType width)
835 {
836 if (context == FORMAT && width == ABBREVIATED) {
837 if (fShortYearNames) {
838 delete[] fShortYearNames;
839 }
840 fShortYearNames = newUnicodeStringArray(count);
841 uprv_arrayCopy(yearNames, fShortYearNames, count);
842 fShortYearNamesCount = count;
843 }
844 }
845
846 const UnicodeString*
getZodiacNames(int32_t & count,DtContextType,DtWidthType) const847 DateFormatSymbols::getZodiacNames(int32_t& count,
848 DtContextType /*ignored*/, DtWidthType /*ignored*/) const
849 {
850 count = fShortZodiacNamesCount;
851 return fShortZodiacNames;
852 }
853
854 void
setZodiacNames(const UnicodeString * zodiacNames,int32_t count,DtContextType context,DtWidthType width)855 DateFormatSymbols::setZodiacNames(const UnicodeString* zodiacNames, int32_t count,
856 DtContextType context, DtWidthType width)
857 {
858 if (context == FORMAT && width == ABBREVIATED) {
859 if (fShortZodiacNames) {
860 delete[] fShortZodiacNames;
861 }
862 fShortZodiacNames = newUnicodeStringArray(count);
863 uprv_arrayCopy(zodiacNames, fShortZodiacNames, count);
864 fShortZodiacNamesCount = count;
865 }
866 }
867
868 //------------------------------------------------------
869
870 void
setEras(const UnicodeString * erasArray,int32_t count)871 DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
872 {
873 // delete the old list if we own it
874 if (fEras)
875 delete[] fEras;
876
877 // we always own the new list, which we create here (we duplicate rather
878 // than adopting the list passed in)
879 fEras = newUnicodeStringArray(count);
880 uprv_arrayCopy(erasArray,fEras, count);
881 fErasCount = count;
882 }
883
884 void
setEraNames(const UnicodeString * eraNamesArray,int32_t count)885 DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)
886 {
887 // delete the old list if we own it
888 if (fEraNames)
889 delete[] fEraNames;
890
891 // we always own the new list, which we create here (we duplicate rather
892 // than adopting the list passed in)
893 fEraNames = newUnicodeStringArray(count);
894 uprv_arrayCopy(eraNamesArray,fEraNames, count);
895 fEraNamesCount = count;
896 }
897
898 void
setNarrowEras(const UnicodeString * narrowErasArray,int32_t count)899 DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)
900 {
901 // delete the old list if we own it
902 if (fNarrowEras)
903 delete[] fNarrowEras;
904
905 // we always own the new list, which we create here (we duplicate rather
906 // than adopting the list passed in)
907 fNarrowEras = newUnicodeStringArray(count);
908 uprv_arrayCopy(narrowErasArray,fNarrowEras, count);
909 fNarrowErasCount = count;
910 }
911
912 void
setMonths(const UnicodeString * monthsArray,int32_t count)913 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
914 {
915 // delete the old list if we own it
916 if (fMonths)
917 delete[] fMonths;
918
919 // we always own the new list, which we create here (we duplicate rather
920 // than adopting the list passed in)
921 fMonths = newUnicodeStringArray(count);
922 uprv_arrayCopy( monthsArray,fMonths,count);
923 fMonthsCount = count;
924 }
925
926 void
setShortMonths(const UnicodeString * shortMonthsArray,int32_t count)927 DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
928 {
929 // delete the old list if we own it
930 if (fShortMonths)
931 delete[] fShortMonths;
932
933 // we always own the new list, which we create here (we duplicate rather
934 // than adopting the list passed in)
935 fShortMonths = newUnicodeStringArray(count);
936 uprv_arrayCopy(shortMonthsArray,fShortMonths, count);
937 fShortMonthsCount = count;
938 }
939
940 void
setMonths(const UnicodeString * monthsArray,int32_t count,DtContextType context,DtWidthType width)941 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)
942 {
943 // delete the old list if we own it
944 // we always own the new list, which we create here (we duplicate rather
945 // than adopting the list passed in)
946
947 switch (context) {
948 case FORMAT :
949 switch (width) {
950 case WIDE :
951 if (fMonths)
952 delete[] fMonths;
953 fMonths = newUnicodeStringArray(count);
954 uprv_arrayCopy( monthsArray,fMonths,count);
955 fMonthsCount = count;
956 break;
957 case ABBREVIATED :
958 if (fShortMonths)
959 delete[] fShortMonths;
960 fShortMonths = newUnicodeStringArray(count);
961 uprv_arrayCopy( monthsArray,fShortMonths,count);
962 fShortMonthsCount = count;
963 break;
964 case NARROW :
965 if (fNarrowMonths)
966 delete[] fNarrowMonths;
967 fNarrowMonths = newUnicodeStringArray(count);
968 uprv_arrayCopy( monthsArray,fNarrowMonths,count);
969 fNarrowMonthsCount = count;
970 break;
971 default :
972 break;
973 }
974 break;
975 case STANDALONE :
976 switch (width) {
977 case WIDE :
978 if (fStandaloneMonths)
979 delete[] fStandaloneMonths;
980 fStandaloneMonths = newUnicodeStringArray(count);
981 uprv_arrayCopy( monthsArray,fStandaloneMonths,count);
982 fStandaloneMonthsCount = count;
983 break;
984 case ABBREVIATED :
985 if (fStandaloneShortMonths)
986 delete[] fStandaloneShortMonths;
987 fStandaloneShortMonths = newUnicodeStringArray(count);
988 uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count);
989 fStandaloneShortMonthsCount = count;
990 break;
991 case NARROW :
992 if (fStandaloneNarrowMonths)
993 delete[] fStandaloneNarrowMonths;
994 fStandaloneNarrowMonths = newUnicodeStringArray(count);
995 uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count);
996 fStandaloneNarrowMonthsCount = count;
997 break;
998 default :
999 break;
1000 }
1001 break;
1002 case DT_CONTEXT_COUNT :
1003 break;
1004 }
1005 }
1006
setWeekdays(const UnicodeString * weekdaysArray,int32_t count)1007 void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
1008 {
1009 // delete the old list if we own it
1010 if (fWeekdays)
1011 delete[] fWeekdays;
1012
1013 // we always own the new list, which we create here (we duplicate rather
1014 // than adopting the list passed in)
1015 fWeekdays = newUnicodeStringArray(count);
1016 uprv_arrayCopy(weekdaysArray,fWeekdays,count);
1017 fWeekdaysCount = count;
1018 }
1019
1020 void
setShortWeekdays(const UnicodeString * shortWeekdaysArray,int32_t count)1021 DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
1022 {
1023 // delete the old list if we own it
1024 if (fShortWeekdays)
1025 delete[] fShortWeekdays;
1026
1027 // we always own the new list, which we create here (we duplicate rather
1028 // than adopting the list passed in)
1029 fShortWeekdays = newUnicodeStringArray(count);
1030 uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);
1031 fShortWeekdaysCount = count;
1032 }
1033
1034 void
setWeekdays(const UnicodeString * weekdaysArray,int32_t count,DtContextType context,DtWidthType width)1035 DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)
1036 {
1037 // delete the old list if we own it
1038 // we always own the new list, which we create here (we duplicate rather
1039 // than adopting the list passed in)
1040
1041 switch (context) {
1042 case FORMAT :
1043 switch (width) {
1044 case WIDE :
1045 if (fWeekdays)
1046 delete[] fWeekdays;
1047 fWeekdays = newUnicodeStringArray(count);
1048 uprv_arrayCopy(weekdaysArray, fWeekdays, count);
1049 fWeekdaysCount = count;
1050 break;
1051 case ABBREVIATED :
1052 if (fShortWeekdays)
1053 delete[] fShortWeekdays;
1054 fShortWeekdays = newUnicodeStringArray(count);
1055 uprv_arrayCopy(weekdaysArray, fShortWeekdays, count);
1056 fShortWeekdaysCount = count;
1057 break;
1058 case SHORT :
1059 if (fShorterWeekdays)
1060 delete[] fShorterWeekdays;
1061 fShorterWeekdays = newUnicodeStringArray(count);
1062 uprv_arrayCopy(weekdaysArray, fShorterWeekdays, count);
1063 fShorterWeekdaysCount = count;
1064 break;
1065 case NARROW :
1066 if (fNarrowWeekdays)
1067 delete[] fNarrowWeekdays;
1068 fNarrowWeekdays = newUnicodeStringArray(count);
1069 uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count);
1070 fNarrowWeekdaysCount = count;
1071 break;
1072 case DT_WIDTH_COUNT :
1073 break;
1074 }
1075 break;
1076 case STANDALONE :
1077 switch (width) {
1078 case WIDE :
1079 if (fStandaloneWeekdays)
1080 delete[] fStandaloneWeekdays;
1081 fStandaloneWeekdays = newUnicodeStringArray(count);
1082 uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count);
1083 fStandaloneWeekdaysCount = count;
1084 break;
1085 case ABBREVIATED :
1086 if (fStandaloneShortWeekdays)
1087 delete[] fStandaloneShortWeekdays;
1088 fStandaloneShortWeekdays = newUnicodeStringArray(count);
1089 uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count);
1090 fStandaloneShortWeekdaysCount = count;
1091 break;
1092 case SHORT :
1093 if (fStandaloneShorterWeekdays)
1094 delete[] fStandaloneShorterWeekdays;
1095 fStandaloneShorterWeekdays = newUnicodeStringArray(count);
1096 uprv_arrayCopy(weekdaysArray, fStandaloneShorterWeekdays, count);
1097 fStandaloneShorterWeekdaysCount = count;
1098 break;
1099 case NARROW :
1100 if (fStandaloneNarrowWeekdays)
1101 delete[] fStandaloneNarrowWeekdays;
1102 fStandaloneNarrowWeekdays = newUnicodeStringArray(count);
1103 uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count);
1104 fStandaloneNarrowWeekdaysCount = count;
1105 break;
1106 case DT_WIDTH_COUNT :
1107 break;
1108 }
1109 break;
1110 case DT_CONTEXT_COUNT :
1111 break;
1112 }
1113 }
1114
1115 void
setQuarters(const UnicodeString * quartersArray,int32_t count,DtContextType context,DtWidthType width)1116 DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)
1117 {
1118 // delete the old list if we own it
1119 // we always own the new list, which we create here (we duplicate rather
1120 // than adopting the list passed in)
1121
1122 switch (context) {
1123 case FORMAT :
1124 switch (width) {
1125 case WIDE :
1126 if (fQuarters)
1127 delete[] fQuarters;
1128 fQuarters = newUnicodeStringArray(count);
1129 uprv_arrayCopy( quartersArray,fQuarters,count);
1130 fQuartersCount = count;
1131 break;
1132 case ABBREVIATED :
1133 if (fShortQuarters)
1134 delete[] fShortQuarters;
1135 fShortQuarters = newUnicodeStringArray(count);
1136 uprv_arrayCopy( quartersArray,fShortQuarters,count);
1137 fShortQuartersCount = count;
1138 break;
1139 case NARROW :
1140 /*
1141 if (fNarrowQuarters)
1142 delete[] fNarrowQuarters;
1143 fNarrowQuarters = newUnicodeStringArray(count);
1144 uprv_arrayCopy( quartersArray,fNarrowQuarters,count);
1145 fNarrowQuartersCount = count;
1146 */
1147 break;
1148 default :
1149 break;
1150 }
1151 break;
1152 case STANDALONE :
1153 switch (width) {
1154 case WIDE :
1155 if (fStandaloneQuarters)
1156 delete[] fStandaloneQuarters;
1157 fStandaloneQuarters = newUnicodeStringArray(count);
1158 uprv_arrayCopy( quartersArray,fStandaloneQuarters,count);
1159 fStandaloneQuartersCount = count;
1160 break;
1161 case ABBREVIATED :
1162 if (fStandaloneShortQuarters)
1163 delete[] fStandaloneShortQuarters;
1164 fStandaloneShortQuarters = newUnicodeStringArray(count);
1165 uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count);
1166 fStandaloneShortQuartersCount = count;
1167 break;
1168 case NARROW :
1169 /*
1170 if (fStandaloneNarrowQuarters)
1171 delete[] fStandaloneNarrowQuarters;
1172 fStandaloneNarrowQuarters = newUnicodeStringArray(count);
1173 uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count);
1174 fStandaloneNarrowQuartersCount = count;
1175 */
1176 break;
1177 default :
1178 break;
1179 }
1180 break;
1181 case DT_CONTEXT_COUNT :
1182 break;
1183 }
1184 }
1185
1186 void
setAmPmStrings(const UnicodeString * amPmsArray,int32_t count)1187 DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
1188 {
1189 // delete the old list if we own it
1190 if (fAmPms) delete[] fAmPms;
1191
1192 // we always own the new list, which we create here (we duplicate rather
1193 // than adopting the list passed in)
1194 fAmPms = newUnicodeStringArray(count);
1195 uprv_arrayCopy(amPmsArray,fAmPms,count);
1196 fAmPmsCount = count;
1197 }
1198
1199 void
setTimeSeparatorString(const UnicodeString & newTimeSeparator)1200 DateFormatSymbols::setTimeSeparatorString(const UnicodeString& newTimeSeparator)
1201 {
1202 fTimeSeparator = newTimeSeparator;
1203 }
1204
1205 const UnicodeString**
getZoneStrings(int32_t & rowCount,int32_t & columnCount) const1206 DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
1207 {
1208 const UnicodeString **result = NULL;
1209
1210 umtx_lock(&LOCK);
1211 if (fZoneStrings == NULL) {
1212 if (fLocaleZoneStrings == NULL) {
1213 ((DateFormatSymbols*)this)->initZoneStringsArray();
1214 }
1215 result = (const UnicodeString**)fLocaleZoneStrings;
1216 } else {
1217 result = (const UnicodeString**)fZoneStrings;
1218 }
1219 rowCount = fZoneStringsRowCount;
1220 columnCount = fZoneStringsColCount;
1221 umtx_unlock(&LOCK);
1222
1223 return result;
1224 }
1225
1226 // For now, we include all zones
1227 #define ZONE_SET UCAL_ZONE_TYPE_ANY
1228
1229 // This code must be called within a synchronized block
1230 void
initZoneStringsArray(void)1231 DateFormatSymbols::initZoneStringsArray(void) {
1232 if (fZoneStrings != NULL || fLocaleZoneStrings != NULL) {
1233 return;
1234 }
1235
1236 UErrorCode status = U_ZERO_ERROR;
1237
1238 StringEnumeration *tzids = NULL;
1239 UnicodeString ** zarray = NULL;
1240 TimeZoneNames *tzNames = NULL;
1241 int32_t rows = 0;
1242
1243 do { // dummy do-while
1244
1245 tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status);
1246 rows = tzids->count(status);
1247 if (U_FAILURE(status)) {
1248 break;
1249 }
1250
1251 // Allocate array
1252 int32_t size = rows * sizeof(UnicodeString*);
1253 zarray = (UnicodeString**)uprv_malloc(size);
1254 if (zarray == NULL) {
1255 status = U_MEMORY_ALLOCATION_ERROR;
1256 break;
1257 }
1258 uprv_memset(zarray, 0, size);
1259
1260 tzNames = TimeZoneNames::createInstance(fZSFLocale, status);
1261
1262 const UnicodeString *tzid;
1263 int32_t i = 0;
1264 UDate now = Calendar::getNow();
1265 UnicodeString tzDispName;
1266
1267 while ((tzid = tzids->snext(status))) {
1268 if (U_FAILURE(status)) {
1269 break;
1270 }
1271
1272 zarray[i] = new UnicodeString[5];
1273 if (zarray[i] == NULL) {
1274 status = U_MEMORY_ALLOCATION_ERROR;
1275 break;
1276 }
1277
1278 zarray[i][0].setTo(*tzid);
1279 zarray[i][1].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_STANDARD, now, tzDispName));
1280 zarray[i][2].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_STANDARD, now, tzDispName));
1281 zarray[i][3].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_DAYLIGHT, now, tzDispName));
1282 zarray[i][4].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_DAYLIGHT, now, tzDispName));
1283 i++;
1284 }
1285
1286 } while (FALSE);
1287
1288 if (U_FAILURE(status)) {
1289 if (zarray) {
1290 for (int32_t i = 0; i < rows; i++) {
1291 if (zarray[i]) {
1292 delete[] zarray[i];
1293 }
1294 }
1295 uprv_free(zarray);
1296 }
1297 }
1298
1299 if (tzNames) {
1300 delete tzNames;
1301 }
1302 if (tzids) {
1303 delete tzids;
1304 }
1305
1306 fLocaleZoneStrings = zarray;
1307 fZoneStringsRowCount = rows;
1308 fZoneStringsColCount = 5;
1309 }
1310
1311 void
setZoneStrings(const UnicodeString * const * strings,int32_t rowCount,int32_t columnCount)1312 DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)
1313 {
1314 // since deleting a 2-d array is a pain in the butt, we offload that task to
1315 // a separate function
1316 disposeZoneStrings();
1317 // we always own the new list, which we create here (we duplicate rather
1318 // than adopting the list passed in)
1319 fZoneStringsRowCount = rowCount;
1320 fZoneStringsColCount = columnCount;
1321 createZoneStrings((const UnicodeString**)strings);
1322 }
1323
1324 //------------------------------------------------------
1325
1326 const UChar * U_EXPORT2
getPatternUChars(void)1327 DateFormatSymbols::getPatternUChars(void)
1328 {
1329 return gPatternChars;
1330 }
1331
1332 UDateFormatField U_EXPORT2
getPatternCharIndex(UChar c)1333 DateFormatSymbols::getPatternCharIndex(UChar c) {
1334 const UChar *p = u_strchr(gPatternChars, c);
1335 if (p == NULL) {
1336 return UDAT_FIELD_COUNT;
1337 } else {
1338 return static_cast<UDateFormatField>(p - gPatternChars);
1339 }
1340 }
1341
1342 static const uint64_t kNumericFieldsAlways =
1343 ((uint64_t)1 << UDAT_YEAR_FIELD) | // y
1344 ((uint64_t)1 << UDAT_DATE_FIELD) | // d
1345 ((uint64_t)1 << UDAT_HOUR_OF_DAY1_FIELD) | // k
1346 ((uint64_t)1 << UDAT_HOUR_OF_DAY0_FIELD) | // H
1347 ((uint64_t)1 << UDAT_MINUTE_FIELD) | // m
1348 ((uint64_t)1 << UDAT_SECOND_FIELD) | // s
1349 ((uint64_t)1 << UDAT_FRACTIONAL_SECOND_FIELD) | // S
1350 ((uint64_t)1 << UDAT_DAY_OF_YEAR_FIELD) | // D
1351 ((uint64_t)1 << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) | // F
1352 ((uint64_t)1 << UDAT_WEEK_OF_YEAR_FIELD) | // w
1353 ((uint64_t)1 << UDAT_WEEK_OF_MONTH_FIELD) | // W
1354 ((uint64_t)1 << UDAT_HOUR1_FIELD) | // h
1355 ((uint64_t)1 << UDAT_HOUR0_FIELD) | // K
1356 ((uint64_t)1 << UDAT_YEAR_WOY_FIELD) | // Y
1357 ((uint64_t)1 << UDAT_EXTENDED_YEAR_FIELD) | // u
1358 ((uint64_t)1 << UDAT_JULIAN_DAY_FIELD) | // g
1359 ((uint64_t)1 << UDAT_MILLISECONDS_IN_DAY_FIELD) | // A
1360 ((uint64_t)1 << UDAT_RELATED_YEAR_FIELD); // r
1361
1362 static const uint64_t kNumericFieldsForCount12 =
1363 ((uint64_t)1 << UDAT_MONTH_FIELD) | // M or MM
1364 ((uint64_t)1 << UDAT_DOW_LOCAL_FIELD) | // e or ee
1365 ((uint64_t)1 << UDAT_STANDALONE_DAY_FIELD) | // c or cc
1366 ((uint64_t)1 << UDAT_STANDALONE_MONTH_FIELD) | // L or LL
1367 ((uint64_t)1 << UDAT_QUARTER_FIELD) | // Q or QQ
1368 ((uint64_t)1 << UDAT_STANDALONE_QUARTER_FIELD); // q or qq
1369
1370 UBool U_EXPORT2
isNumericField(UDateFormatField f,int32_t count)1371 DateFormatSymbols::isNumericField(UDateFormatField f, int32_t count) {
1372 if (f == UDAT_FIELD_COUNT) {
1373 return FALSE;
1374 }
1375 uint64_t flag = ((uint64_t)1 << f);
1376 return ((kNumericFieldsAlways & flag) != 0 || ((kNumericFieldsForCount12 & flag) != 0 && count < 3));
1377 }
1378
1379 UBool U_EXPORT2
isNumericPatternChar(UChar c,int32_t count)1380 DateFormatSymbols::isNumericPatternChar(UChar c, int32_t count) {
1381 return isNumericField(getPatternCharIndex(c), count);
1382 }
1383
1384 //------------------------------------------------------
1385
1386 UnicodeString&
getLocalPatternChars(UnicodeString & result) const1387 DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
1388 {
1389 // fastCopyFrom() - see assignArray comments
1390 return result.fastCopyFrom(fLocalPatternChars);
1391 }
1392
1393 //------------------------------------------------------
1394
1395 void
setLocalPatternChars(const UnicodeString & newLocalPatternChars)1396 DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
1397 {
1398 fLocalPatternChars = newLocalPatternChars;
1399 }
1400
1401 //------------------------------------------------------
1402
1403 static void
initField(UnicodeString ** field,int32_t & length,const UResourceBundle * data,UErrorCode & status)1404 initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) {
1405 if (U_SUCCESS(status)) {
1406 int32_t strLen = 0;
1407 length = ures_getSize(data);
1408 *field = newUnicodeStringArray(length);
1409 if (*field) {
1410 for(int32_t i = 0; i<length; i++) {
1411 const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status);
1412 // setTo() - see assignArray comments
1413 (*(field)+i)->setTo(TRUE, resStr, strLen);
1414 }
1415 }
1416 else {
1417 length = 0;
1418 status = U_MEMORY_ALLOCATION_ERROR;
1419 }
1420 }
1421 }
1422
1423 static void
initField(UnicodeString ** field,int32_t & length,const UChar * data,LastResortSize numStr,LastResortSize strLen,UErrorCode & status)1424 initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) {
1425 if (U_SUCCESS(status)) {
1426 length = numStr;
1427 *field = newUnicodeStringArray((size_t)numStr);
1428 if (*field) {
1429 for(int32_t i = 0; i<length; i++) {
1430 // readonly aliases - all "data" strings are constant
1431 // -1 as length for variable-length strings (gLastResortDayNames[0] is empty)
1432 (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1);
1433 }
1434 }
1435 else {
1436 length = 0;
1437 status = U_MEMORY_ALLOCATION_ERROR;
1438 }
1439 }
1440 }
1441
1442 static void
initLeapMonthPattern(UnicodeString * field,int32_t index,const UResourceBundle * data,UErrorCode & status)1443 initLeapMonthPattern(UnicodeString *field, int32_t index, const UResourceBundle *data, UErrorCode &status) {
1444 field[index].remove();
1445 if (U_SUCCESS(status)) {
1446 int32_t strLen = 0;
1447 const UChar *resStr = ures_getStringByKey(data, gNamesLeapTag, &strLen, &status);
1448 if (U_SUCCESS(status)) {
1449 field[index].setTo(TRUE, resStr, strLen);
1450 }
1451 }
1452 status = U_ZERO_ERROR;
1453 }
1454
1455 typedef struct {
1456 const char * usageTypeName;
1457 DateFormatSymbols::ECapitalizationContextUsageType usageTypeEnumValue;
1458 } ContextUsageTypeNameToEnumValue;
1459
1460 static const ContextUsageTypeNameToEnumValue contextUsageTypeMap[] = {
1461 // Entries must be sorted by usageTypeName; entry with NULL name terminates list.
1462 { "day-format-except-narrow", DateFormatSymbols::kCapContextUsageDayFormat },
1463 { "day-narrow", DateFormatSymbols::kCapContextUsageDayNarrow },
1464 { "day-standalone-except-narrow", DateFormatSymbols::kCapContextUsageDayStandalone },
1465 { "era-abbr", DateFormatSymbols::kCapContextUsageEraAbbrev },
1466 { "era-name", DateFormatSymbols::kCapContextUsageEraWide },
1467 { "era-narrow", DateFormatSymbols::kCapContextUsageEraNarrow },
1468 { "metazone-long", DateFormatSymbols::kCapContextUsageMetazoneLong },
1469 { "metazone-short", DateFormatSymbols::kCapContextUsageMetazoneShort },
1470 { "month-format-except-narrow", DateFormatSymbols::kCapContextUsageMonthFormat },
1471 { "month-narrow", DateFormatSymbols::kCapContextUsageMonthNarrow },
1472 { "month-standalone-except-narrow", DateFormatSymbols::kCapContextUsageMonthStandalone },
1473 { "zone-long", DateFormatSymbols::kCapContextUsageZoneLong },
1474 { "zone-short", DateFormatSymbols::kCapContextUsageZoneShort },
1475 { NULL, (DateFormatSymbols::ECapitalizationContextUsageType)0 },
1476 };
1477
1478 void
initializeData(const Locale & locale,const char * type,UErrorCode & status,UBool useLastResortData)1479 DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData)
1480 {
1481 int32_t i;
1482 int32_t len = 0;
1483 const UChar *resStr;
1484 /* In case something goes wrong, initialize all of the data to NULL. */
1485 fEras = NULL;
1486 fErasCount = 0;
1487 fEraNames = NULL;
1488 fEraNamesCount = 0;
1489 fNarrowEras = NULL;
1490 fNarrowErasCount = 0;
1491 fMonths = NULL;
1492 fMonthsCount=0;
1493 fShortMonths = NULL;
1494 fShortMonthsCount=0;
1495 fNarrowMonths = NULL;
1496 fNarrowMonthsCount=0;
1497 fStandaloneMonths = NULL;
1498 fStandaloneMonthsCount=0;
1499 fStandaloneShortMonths = NULL;
1500 fStandaloneShortMonthsCount=0;
1501 fStandaloneNarrowMonths = NULL;
1502 fStandaloneNarrowMonthsCount=0;
1503 fWeekdays = NULL;
1504 fWeekdaysCount=0;
1505 fShortWeekdays = NULL;
1506 fShortWeekdaysCount=0;
1507 fShorterWeekdays = NULL;
1508 fShorterWeekdaysCount=0;
1509 fNarrowWeekdays = NULL;
1510 fNarrowWeekdaysCount=0;
1511 fStandaloneWeekdays = NULL;
1512 fStandaloneWeekdaysCount=0;
1513 fStandaloneShortWeekdays = NULL;
1514 fStandaloneShortWeekdaysCount=0;
1515 fStandaloneShorterWeekdays = NULL;
1516 fStandaloneShorterWeekdaysCount=0;
1517 fStandaloneNarrowWeekdays = NULL;
1518 fStandaloneNarrowWeekdaysCount=0;
1519 fAmPms = NULL;
1520 fAmPmsCount=0;
1521 fNarrowAmPms = NULL;
1522 fNarrowAmPmsCount=0;
1523 fTimeSeparator.setToBogus();
1524 fQuarters = NULL;
1525 fQuartersCount = 0;
1526 fShortQuarters = NULL;
1527 fShortQuartersCount = 0;
1528 fStandaloneQuarters = NULL;
1529 fStandaloneQuartersCount = 0;
1530 fStandaloneShortQuarters = NULL;
1531 fStandaloneShortQuartersCount = 0;
1532 fLeapMonthPatterns = NULL;
1533 fLeapMonthPatternsCount = 0;
1534 fShortYearNames = NULL;
1535 fShortYearNamesCount = 0;
1536 fShortZodiacNames = NULL;
1537 fShortZodiacNamesCount = 0;
1538 fZoneStringsRowCount = 0;
1539 fZoneStringsColCount = 0;
1540 fZoneStrings = NULL;
1541 fLocaleZoneStrings = NULL;
1542 uprv_memset(fCapitalization, 0, sizeof(fCapitalization));
1543
1544 // We need to preserve the requested locale for
1545 // lazy ZoneStringFormat instantiation. ZoneStringFormat
1546 // is region sensitive, thus, bundle locale bundle's locale
1547 // is not sufficient.
1548 fZSFLocale = locale;
1549
1550 if (U_FAILURE(status)) return;
1551
1552 /**
1553 * Retrieve the string arrays we need from the resource bundle file.
1554 * We cast away const here, but that's okay; we won't delete any of
1555 * these.
1556 */
1557 CalendarData calData(locale, type, status);
1558
1559 // load the first data item
1560 UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
1561 UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
1562 UErrorCode oldStatus = status;
1563 UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status);
1564 if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3
1565 status = oldStatus;
1566 eraNames = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
1567 }
1568 // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too
1569 oldStatus = status;
1570 UResourceBundle *narrowEras = ures_getByKeyWithFallback(erasMain, gNamesNarrowTag, NULL, &status);
1571 if ( status == U_MISSING_RESOURCE_ERROR ) {
1572 status = oldStatus;
1573 narrowEras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
1574 }
1575
1576 UErrorCode tempStatus = U_ZERO_ERROR;
1577 UResourceBundle *monthPatterns = calData.getByKey(gMonthPatternsTag, tempStatus);
1578 if (U_SUCCESS(tempStatus) && monthPatterns != NULL) {
1579 fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount);
1580 if (fLeapMonthPatterns) {
1581 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calData.getByKey2(gMonthPatternsTag, gNamesWideTag, tempStatus), tempStatus);
1582 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calData.getByKey2(gMonthPatternsTag, gNamesAbbrTag, tempStatus), tempStatus);
1583 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calData.getByKey2(gMonthPatternsTag, gNamesNarrowTag, tempStatus), tempStatus);
1584 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus);
1585 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus);
1586 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus);
1587 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calData.getByKey3(gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus);
1588 if (U_SUCCESS(tempStatus)) {
1589 // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't.
1590 // The ordering of the following statements is important.
1591 if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) {
1592 fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
1593 };
1594 if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) {
1595 fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]);
1596 };
1597 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) {
1598 fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
1599 };
1600 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) {
1601 fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]);
1602 };
1603 // end of hack
1604 fLeapMonthPatternsCount = kMonthPatternsCount;
1605 } else {
1606 delete[] fLeapMonthPatterns;
1607 fLeapMonthPatterns = NULL;
1608 }
1609 }
1610 }
1611
1612 tempStatus = U_ZERO_ERROR;
1613 UResourceBundle *cyclicNameSets= calData.getByKey(gCyclicNameSetsTag, tempStatus);
1614 if (U_SUCCESS(tempStatus) && cyclicNameSets != NULL) {
1615 UResourceBundle *nameSetYears = ures_getByKeyWithFallback(cyclicNameSets, gNameSetYearsTag, NULL, &tempStatus);
1616 if (U_SUCCESS(tempStatus)) {
1617 UResourceBundle *nameSetYearsFmt = ures_getByKeyWithFallback(nameSetYears, gNamesFormatTag, NULL, &tempStatus);
1618 if (U_SUCCESS(tempStatus)) {
1619 UResourceBundle *nameSetYearsFmtAbbrev = ures_getByKeyWithFallback(nameSetYearsFmt, gNamesAbbrTag, NULL, &tempStatus);
1620 if (U_SUCCESS(tempStatus)) {
1621 initField(&fShortYearNames, fShortYearNamesCount, nameSetYearsFmtAbbrev, tempStatus);
1622 ures_close(nameSetYearsFmtAbbrev);
1623 }
1624 ures_close(nameSetYearsFmt);
1625 }
1626 ures_close(nameSetYears);
1627 }
1628 UResourceBundle *nameSetZodiacs = ures_getByKeyWithFallback(cyclicNameSets, gNameSetZodiacsTag, NULL, &tempStatus);
1629 if (U_SUCCESS(tempStatus)) {
1630 UResourceBundle *nameSetZodiacsFmt = ures_getByKeyWithFallback(nameSetZodiacs, gNamesFormatTag, NULL, &tempStatus);
1631 if (U_SUCCESS(tempStatus)) {
1632 UResourceBundle *nameSetZodiacsFmtAbbrev = ures_getByKeyWithFallback(nameSetZodiacsFmt, gNamesAbbrTag, NULL, &tempStatus);
1633 if (U_SUCCESS(tempStatus)) {
1634 initField(&fShortZodiacNames, fShortZodiacNamesCount, nameSetZodiacsFmtAbbrev, tempStatus);
1635 ures_close(nameSetZodiacsFmtAbbrev);
1636 }
1637 ures_close(nameSetZodiacsFmt);
1638 }
1639 ures_close(nameSetZodiacs);
1640 }
1641 }
1642
1643 tempStatus = U_ZERO_ERROR;
1644 UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus);
1645 if (U_SUCCESS(tempStatus)) {
1646 UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, gContextTransformsTag, NULL, &tempStatus);
1647 if (U_SUCCESS(tempStatus)) {
1648 UResourceBundle *contextTransformUsage;
1649 while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &tempStatus)) != NULL ) {
1650 const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);
1651 if (U_SUCCESS(tempStatus) && intVector != NULL && len >= 2) {
1652 const char* usageType = ures_getKey(contextTransformUsage);
1653 if (usageType != NULL) {
1654 const ContextUsageTypeNameToEnumValue * typeMapPtr = contextUsageTypeMap;
1655 int32_t compResult = 0;
1656 // linear search; list is short and we cannot be sure that bsearch is available
1657 while ( typeMapPtr->usageTypeName != NULL && (compResult = uprv_strcmp(usageType, typeMapPtr->usageTypeName)) > 0 ) {
1658 ++typeMapPtr;
1659 }
1660 if (typeMapPtr->usageTypeName != NULL && compResult == 0) {
1661 fCapitalization[typeMapPtr->usageTypeEnumValue][0] = intVector[0];
1662 fCapitalization[typeMapPtr->usageTypeEnumValue][1] = intVector[1];
1663 }
1664 }
1665 }
1666 tempStatus = U_ZERO_ERROR;
1667 ures_close(contextTransformUsage);
1668 }
1669 ures_close(contextTransforms);
1670 }
1671
1672 tempStatus = U_ZERO_ERROR;
1673 const LocalPointer<NumberingSystem> numberingSystem(
1674 NumberingSystem::createInstance(locale, tempStatus), tempStatus);
1675 if (U_SUCCESS(tempStatus)) {
1676 // These functions all fail gracefully if passed NULL pointers and
1677 // do nothing unless U_SUCCESS(tempStatus), so it's only necessary
1678 // to check for errors once after all calls are made.
1679 const LocalUResourceBundlePointer numberElementsData(ures_getByKeyWithFallback(
1680 localeBundle, gNumberElementsTag, NULL, &tempStatus));
1681 const LocalUResourceBundlePointer nsNameData(ures_getByKeyWithFallback(
1682 numberElementsData.getAlias(), numberingSystem->getName(), NULL, &tempStatus));
1683 const LocalUResourceBundlePointer symbolsData(ures_getByKeyWithFallback(
1684 nsNameData.getAlias(), gSymbolsTag, NULL, &tempStatus));
1685 fTimeSeparator = ures_getUnicodeStringByKey(
1686 symbolsData.getAlias(), gTimeSeparatorTag, &tempStatus);
1687 if (U_FAILURE(tempStatus)) {
1688 fTimeSeparator.setToBogus();
1689 }
1690 }
1691
1692 ures_close(localeBundle);
1693 }
1694
1695 if (fTimeSeparator.isBogus()) {
1696 fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR);
1697 }
1698
1699 UResourceBundle *weekdaysData = NULL; // Data closed by calData
1700 UResourceBundle *abbrWeekdaysData = NULL; // Data closed by calData
1701 UResourceBundle *shorterWeekdaysData = NULL; // Data closed by calData
1702 UResourceBundle *narrowWeekdaysData = NULL; // Data closed by calData
1703 UResourceBundle *standaloneWeekdaysData = NULL; // Data closed by calData
1704 UResourceBundle *standaloneAbbrWeekdaysData = NULL; // Data closed by calData
1705 UResourceBundle *standaloneShorterWeekdaysData = NULL; // Data closed by calData
1706 UResourceBundle *standaloneNarrowWeekdaysData = NULL; // Data closed by calData
1707
1708 U_LOCALE_BASED(locBased, *this);
1709 if (U_FAILURE(status))
1710 {
1711 if (useLastResortData)
1712 {
1713 // Handle the case in which there is no resource data present.
1714 // We don't have to generate usable patterns in this situation;
1715 // we just need to produce something that will be semi-intelligible
1716 // in most locales.
1717
1718 status = U_USING_FALLBACK_WARNING;
1719
1720 initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
1721 initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
1722 initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
1723 initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1724 initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1725 initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1726 initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1727 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1728 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
1729 initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1730 initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1731 initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1732 initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1733 initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1734 initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1735 initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1736 initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
1737 initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
1738 initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
1739 initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
1740 initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
1741 initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
1742 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
1743 fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
1744 }
1745 goto cleanup;
1746 }
1747
1748 // if we make it to here, the resource data is cool, and we can get everything out
1749 // of it that we need except for the time-zone and localized-pattern data, which
1750 // are stored in a separate file
1751 locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status),
1752 ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status));
1753
1754 initField(&fEras, fErasCount, eras, status);
1755 initField(&fEraNames, fEraNamesCount, eraNames, status);
1756 initField(&fNarrowEras, fNarrowErasCount, narrowEras, status);
1757
1758 initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
1759 initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
1760
1761 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
1762 if(status == U_MISSING_RESOURCE_ERROR) {
1763 status = U_ZERO_ERROR;
1764 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
1765 }
1766 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If format/narrow not available, use format/abbreviated */
1767 status = U_ZERO_ERROR;
1768 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
1769 }
1770
1771 initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status);
1772 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/wide not available, use format/wide */
1773 status = U_ZERO_ERROR;
1774 initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
1775 }
1776 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
1777 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/abbreviated not available, use format/abbreviated */
1778 status = U_ZERO_ERROR;
1779 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
1780 }
1781 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
1782 if ( status == U_MISSING_RESOURCE_ERROR ) { /* if standalone/narrow not availabe, try format/narrow */
1783 status = U_ZERO_ERROR;
1784 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
1785 if ( status == U_MISSING_RESOURCE_ERROR ) { /* if still not there, use format/abbreviated */
1786 status = U_ZERO_ERROR;
1787 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
1788 }
1789 }
1790 initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);
1791 initField(&fNarrowAmPms, fNarrowAmPmsCount, calData.getByKey(gAmPmMarkersNarrowTag, status), status);
1792
1793 initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
1794 initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
1795
1796 initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status);
1797 if(status == U_MISSING_RESOURCE_ERROR) {
1798 status = U_ZERO_ERROR;
1799 initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
1800 }
1801
1802 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
1803 if(status == U_MISSING_RESOURCE_ERROR) {
1804 status = U_ZERO_ERROR;
1805 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
1806 }
1807
1808 // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597)
1809 /*
1810 // fastCopyFrom()/setTo() - see assignArray comments
1811 resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status);
1812 fLocalPatternChars.setTo(TRUE, resStr, len);
1813 // If the locale data does not include new pattern chars, use the defaults
1814 // TODO: Consider making this an error, since this may add conflicting characters.
1815 if (len < PATTERN_CHARS_LEN) {
1816 fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
1817 }
1818 */
1819 fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
1820
1821 // Format wide weekdays -> fWeekdays
1822 // {sfb} fixed to handle 1-based weekdays
1823 weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
1824 fWeekdaysCount = ures_getSize(weekdaysData);
1825 fWeekdays = new UnicodeString[fWeekdaysCount+1];
1826 /* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/
1827 if (fWeekdays == NULL) {
1828 status = U_MEMORY_ALLOCATION_ERROR;
1829 goto cleanup;
1830 }
1831 // leave fWeekdays[0] empty
1832 for(i = 0; i<fWeekdaysCount; i++) {
1833 resStr = ures_getStringByIndex(weekdaysData, i, &len, &status);
1834 // setTo() - see assignArray comments
1835 fWeekdays[i+1].setTo(TRUE, resStr, len);
1836 }
1837 fWeekdaysCount++;
1838
1839 // Format abbreviated weekdays -> fShortWeekdays
1840 abbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1841 fShortWeekdaysCount = ures_getSize(abbrWeekdaysData);
1842 fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1];
1843 /* test for NULL */
1844 if (fShortWeekdays == 0) {
1845 status = U_MEMORY_ALLOCATION_ERROR;
1846 goto cleanup;
1847 }
1848 // leave fShortWeekdays[0] empty
1849 for(i = 0; i<fShortWeekdaysCount; i++) {
1850 resStr = ures_getStringByIndex(abbrWeekdaysData, i, &len, &status);
1851 // setTo() - see assignArray comments
1852 fShortWeekdays[i+1].setTo(TRUE, resStr, len);
1853 }
1854 fShortWeekdaysCount++;
1855
1856 // Format short weekdays -> fShorterWeekdays (fall back to abbreviated)
1857 shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesShortTag, status);
1858 if ( status == U_MISSING_RESOURCE_ERROR ) {
1859 status = U_ZERO_ERROR;
1860 shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1861 }
1862 fShorterWeekdaysCount = ures_getSize(shorterWeekdaysData);
1863 fShorterWeekdays = new UnicodeString[fShorterWeekdaysCount+1];
1864 /* test for NULL */
1865 if (fShorterWeekdays == 0) {
1866 status = U_MEMORY_ALLOCATION_ERROR;
1867 goto cleanup;
1868 }
1869 // leave fShorterWeekdays[0] empty
1870 for(i = 0; i<fShorterWeekdaysCount; i++) {
1871 resStr = ures_getStringByIndex(shorterWeekdaysData, i, &len, &status);
1872 // setTo() - see assignArray comments
1873 fShorterWeekdays[i+1].setTo(TRUE, resStr, len);
1874 }
1875 fShorterWeekdaysCount++;
1876
1877 // Format narrow weekdays -> fNarrowWeekdays
1878 narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
1879 if(status == U_MISSING_RESOURCE_ERROR) {
1880 status = U_ZERO_ERROR;
1881 narrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
1882 }
1883 if ( status == U_MISSING_RESOURCE_ERROR ) {
1884 status = U_ZERO_ERROR;
1885 narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1886 }
1887 fNarrowWeekdaysCount = ures_getSize(narrowWeekdaysData);
1888 fNarrowWeekdays = new UnicodeString[fNarrowWeekdaysCount+1];
1889 /* test for NULL */
1890 if (fNarrowWeekdays == 0) {
1891 status = U_MEMORY_ALLOCATION_ERROR;
1892 goto cleanup;
1893 }
1894 // leave fNarrowWeekdays[0] empty
1895 for(i = 0; i<fNarrowWeekdaysCount; i++) {
1896 resStr = ures_getStringByIndex(narrowWeekdaysData, i, &len, &status);
1897 // setTo() - see assignArray comments
1898 fNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
1899 }
1900 fNarrowWeekdaysCount++;
1901
1902 // Stand-alone wide weekdays -> fStandaloneWeekdays
1903 standaloneWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status);
1904 if ( status == U_MISSING_RESOURCE_ERROR ) {
1905 status = U_ZERO_ERROR;
1906 standaloneWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
1907 }
1908 fStandaloneWeekdaysCount = ures_getSize(standaloneWeekdaysData);
1909 fStandaloneWeekdays = new UnicodeString[fStandaloneWeekdaysCount+1];
1910 /* test for NULL */
1911 if (fStandaloneWeekdays == 0) {
1912 status = U_MEMORY_ALLOCATION_ERROR;
1913 goto cleanup;
1914 }
1915 // leave fStandaloneWeekdays[0] empty
1916 for(i = 0; i<fStandaloneWeekdaysCount; i++) {
1917 resStr = ures_getStringByIndex(standaloneWeekdaysData, i, &len, &status);
1918 // setTo() - see assignArray comments
1919 fStandaloneWeekdays[i+1].setTo(TRUE, resStr, len);
1920 }
1921 fStandaloneWeekdaysCount++;
1922
1923 // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays
1924 standaloneAbbrWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status);
1925 if ( status == U_MISSING_RESOURCE_ERROR ) {
1926 status = U_ZERO_ERROR;
1927 standaloneAbbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1928 }
1929 fStandaloneShortWeekdaysCount = ures_getSize(standaloneAbbrWeekdaysData);
1930 fStandaloneShortWeekdays = new UnicodeString[fStandaloneShortWeekdaysCount+1];
1931 /* test for NULL */
1932 if (fStandaloneShortWeekdays == 0) {
1933 status = U_MEMORY_ALLOCATION_ERROR;
1934 goto cleanup;
1935 }
1936 // leave fStandaloneShortWeekdays[0] empty
1937 for(i = 0; i<fStandaloneShortWeekdaysCount; i++) {
1938 resStr = ures_getStringByIndex(standaloneAbbrWeekdaysData, i, &len, &status);
1939 // setTo() - see assignArray comments
1940 fStandaloneShortWeekdays[i+1].setTo(TRUE, resStr, len);
1941 }
1942 fStandaloneShortWeekdaysCount++;
1943
1944 // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated)
1945 standaloneShorterWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status);
1946 if ( status == U_MISSING_RESOURCE_ERROR ) {
1947 status = U_ZERO_ERROR;
1948 standaloneShorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1949 }
1950 fStandaloneShorterWeekdaysCount = ures_getSize(standaloneShorterWeekdaysData);
1951 fStandaloneShorterWeekdays = new UnicodeString[fStandaloneShorterWeekdaysCount+1];
1952 /* test for NULL */
1953 if (fStandaloneShorterWeekdays == 0) {
1954 status = U_MEMORY_ALLOCATION_ERROR;
1955 goto cleanup;
1956 }
1957 // leave fStandaloneShorterWeekdays[0] empty
1958 for(i = 0; i<fStandaloneShorterWeekdaysCount; i++) {
1959 resStr = ures_getStringByIndex(standaloneShorterWeekdaysData, i, &len, &status);
1960 // setTo() - see assignArray comments
1961 fStandaloneShorterWeekdays[i+1].setTo(TRUE, resStr, len);
1962 }
1963 fStandaloneShorterWeekdaysCount++;
1964
1965 // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays
1966 standaloneNarrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
1967 if ( status == U_MISSING_RESOURCE_ERROR ) {
1968 status = U_ZERO_ERROR;
1969 standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
1970 if ( status == U_MISSING_RESOURCE_ERROR ) {
1971 status = U_ZERO_ERROR;
1972 standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
1973 }
1974 }
1975 fStandaloneNarrowWeekdaysCount = ures_getSize(standaloneNarrowWeekdaysData);
1976 fStandaloneNarrowWeekdays = new UnicodeString[fStandaloneNarrowWeekdaysCount+1];
1977 /* test for NULL */
1978 if (fStandaloneNarrowWeekdays == 0) {
1979 status = U_MEMORY_ALLOCATION_ERROR;
1980 goto cleanup;
1981 }
1982 // leave fStandaloneNarrowWeekdays[0] empty
1983 for(i = 0; i<fStandaloneNarrowWeekdaysCount; i++) {
1984 resStr = ures_getStringByIndex(standaloneNarrowWeekdaysData, i, &len, &status);
1985 // setTo() - see assignArray comments
1986 fStandaloneNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
1987 }
1988 fStandaloneNarrowWeekdaysCount++;
1989
1990 cleanup:
1991 ures_close(eras);
1992 ures_close(eraNames);
1993 ures_close(narrowEras);
1994 }
1995
1996 Locale
getLocale(ULocDataLocaleType type,UErrorCode & status) const1997 DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
1998 U_LOCALE_BASED(locBased, *this);
1999 return locBased.getLocale(type, status);
2000 }
2001
2002 U_NAMESPACE_END
2003
2004 #endif /* #if !UCONFIG_NO_FORMATTING */
2005
2006 //eof
2007