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