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