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