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