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