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