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