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