1 /* 2 ******************************************************************************* 3 * Copyright (C) 1997-2015, 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/localpointer.h" 27 #include "unicode/dtfmtsym.h" 28 #include "unicode/smpdtfmt.h" 29 #include "unicode/msgfmt.h" 30 #include "unicode/numsys.h" 31 #include "unicode/tznames.h" 32 #include "cpputils.h" 33 #include "umutex.h" 34 #include "cmemory.h" 35 #include "cstring.h" 36 #include "locbased.h" 37 #include "gregoimp.h" 38 #include "hash.h" 39 #include "uresimp.h" 40 #include "ureslocs.h" 41 #include "shareddateformatsymbols.h" 42 #include "unicode/calendar.h" 43 #include "unifiedcache.h" 44 45 // ***************************************************************************** 46 // class DateFormatSymbols 47 // ***************************************************************************** 48 49 /** 50 * These are static arrays we use only in the case where we have no 51 * resource data. 52 */ 53 54 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 55 #define PATTERN_CHARS_LEN 36 56 #else 57 #define PATTERN_CHARS_LEN 35 58 #endif 59 60 /** 61 * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All 62 * locales use the same these unlocalized pattern characters. 63 */ 64 static const UChar gPatternChars[] = { 65 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 66 // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr: 67 #else 68 // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr 69 #endif 70 0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45, 71 0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65, 72 0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0x56, 73 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 74 0x55, 0x4F, 0x58, 0x78, 0x72, 0x3a, 0 75 #else 76 0x55, 0x4F, 0x58, 0x78, 0x72, 0 77 #endif 78 }; 79 80 /* length of an array */ 81 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) 82 83 //------------------------------------------------------ 84 // Strings of last resort. These are only used if we have no resource 85 // files. They aren't designed for actual use, just for backup. 86 87 // These are the month names and abbreviations of last resort. 88 static const UChar gLastResortMonthNames[13][3] = 89 { 90 {0x0030, 0x0031, 0x0000}, /* "01" */ 91 {0x0030, 0x0032, 0x0000}, /* "02" */ 92 {0x0030, 0x0033, 0x0000}, /* "03" */ 93 {0x0030, 0x0034, 0x0000}, /* "04" */ 94 {0x0030, 0x0035, 0x0000}, /* "05" */ 95 {0x0030, 0x0036, 0x0000}, /* "06" */ 96 {0x0030, 0x0037, 0x0000}, /* "07" */ 97 {0x0030, 0x0038, 0x0000}, /* "08" */ 98 {0x0030, 0x0039, 0x0000}, /* "09" */ 99 {0x0031, 0x0030, 0x0000}, /* "10" */ 100 {0x0031, 0x0031, 0x0000}, /* "11" */ 101 {0x0031, 0x0032, 0x0000}, /* "12" */ 102 {0x0031, 0x0033, 0x0000} /* "13" */ 103 }; 104 105 // These are the weekday names and abbreviations of last resort. 106 static const UChar gLastResortDayNames[8][2] = 107 { 108 {0x0030, 0x0000}, /* "0" */ 109 {0x0031, 0x0000}, /* "1" */ 110 {0x0032, 0x0000}, /* "2" */ 111 {0x0033, 0x0000}, /* "3" */ 112 {0x0034, 0x0000}, /* "4" */ 113 {0x0035, 0x0000}, /* "5" */ 114 {0x0036, 0x0000}, /* "6" */ 115 {0x0037, 0x0000} /* "7" */ 116 }; 117 118 // These are the quarter names and abbreviations of last resort. 119 static const UChar gLastResortQuarters[4][2] = 120 { 121 {0x0031, 0x0000}, /* "1" */ 122 {0x0032, 0x0000}, /* "2" */ 123 {0x0033, 0x0000}, /* "3" */ 124 {0x0034, 0x0000}, /* "4" */ 125 }; 126 127 // These are the am/pm and BC/AD markers of last resort. 128 static const UChar gLastResortAmPmMarkers[2][3] = 129 { 130 {0x0041, 0x004D, 0x0000}, /* "AM" */ 131 {0x0050, 0x004D, 0x0000} /* "PM" */ 132 }; 133 134 static const UChar gLastResortEras[2][3] = 135 { 136 {0x0042, 0x0043, 0x0000}, /* "BC" */ 137 {0x0041, 0x0044, 0x0000} /* "AD" */ 138 }; 139 140 /* Sizes for the last resort string arrays */ 141 typedef enum LastResortSize { 142 kMonthNum = 13, 143 kMonthLen = 3, 144 145 kDayNum = 8, 146 kDayLen = 2, 147 148 kAmPmNum = 2, 149 kAmPmLen = 3, 150 151 kQuarterNum = 4, 152 kQuarterLen = 2, 153 154 kEraNum = 2, 155 kEraLen = 3, 156 157 kZoneNum = 5, 158 kZoneLen = 4, 159 160 kGmtHourNum = 4, 161 kGmtHourLen = 10 162 } LastResortSize; 163 164 U_NAMESPACE_BEGIN 165 166 SharedDateFormatSymbols::~SharedDateFormatSymbols() { 167 } 168 169 template<> U_I18N_API 170 const SharedDateFormatSymbols * 171 LocaleCacheKey<SharedDateFormatSymbols>::createObject( 172 const void */*unusedContext*/, UErrorCode &status) const { 173 char type[256]; 174 Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status); 175 if (U_FAILURE(status)) { 176 return NULL; 177 } 178 SharedDateFormatSymbols *shared 179 = new SharedDateFormatSymbols(fLoc, type, status); 180 if (shared == NULL) { 181 status = U_MEMORY_ALLOCATION_ERROR; 182 return NULL; 183 } 184 if (U_FAILURE(status)) { 185 delete shared; 186 return NULL; 187 } 188 shared->addRef(); 189 return shared; 190 } 191 192 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols) 193 194 #define kSUPPLEMENTAL "supplementalData" 195 196 /** 197 * These are the tags we expect to see in normal resource bundle files associated 198 * with a locale and calendar 199 */ 200 static const char gErasTag[]="eras"; 201 static const char gCyclicNameSetsTag[]="cyclicNameSets"; 202 static const char gNameSetYearsTag[]="years"; 203 static const char gNameSetZodiacsTag[]="zodiacs"; 204 static const char gMonthNamesTag[]="monthNames"; 205 static const char gMonthPatternsTag[]="monthPatterns"; 206 static const char gDayNamesTag[]="dayNames"; 207 static const char gNamesWideTag[]="wide"; 208 static const char gNamesAbbrTag[]="abbreviated"; 209 static const char gNamesShortTag[]="short"; 210 static const char gNamesNarrowTag[]="narrow"; 211 static const char gNamesAllTag[]="all"; 212 static const char gNamesLeapTag[]="leap"; 213 static const char gNamesFormatTag[]="format"; 214 static const char gNamesStandaloneTag[]="stand-alone"; 215 static const char gNamesNumericTag[]="numeric"; 216 static const char gAmPmMarkersTag[]="AmPmMarkers"; 217 static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow"; 218 static const char gQuartersTag[]="quarters"; 219 static const char gNumberElementsTag[]="NumberElements"; 220 static const char gSymbolsTag[]="symbols"; 221 static const char gTimeSeparatorTag[]="timeSeparator"; 222 223 // static const char gZoneStringsTag[]="zoneStrings"; 224 225 // static const char gLocalPatternCharsTag[]="localPatternChars"; 226 227 static const char gContextTransformsTag[]="contextTransforms"; 228 229 static UMutex LOCK = U_MUTEX_INITIALIZER; 230 231 /** 232 * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly. 233 * Work around this. 234 */ 235 static inline UnicodeString* newUnicodeStringArray(size_t count) { 236 return new UnicodeString[count ? count : 1]; 237 } 238 239 //------------------------------------------------------ 240 241 DateFormatSymbols * U_EXPORT2 242 DateFormatSymbols::createForLocale( 243 const Locale& locale, UErrorCode &status) { 244 const SharedDateFormatSymbols *shared = NULL; 245 UnifiedCache::getByLocale(locale, shared, status); 246 if (U_FAILURE(status)) { 247 return NULL; 248 } 249 DateFormatSymbols *result = new DateFormatSymbols(shared->get()); 250 shared->removeRef(); 251 if (result == NULL) { 252 status = U_MEMORY_ALLOCATION_ERROR; 253 return NULL; 254 } 255 return result; 256 } 257 258 DateFormatSymbols::DateFormatSymbols(const Locale& locale, 259 UErrorCode& status) 260 : UObject() 261 { 262 initializeData(locale, NULL, status); 263 } 264 265 DateFormatSymbols::DateFormatSymbols(UErrorCode& status) 266 : UObject() 267 { 268 initializeData(Locale::getDefault(), NULL, status, TRUE); 269 } 270 271 272 DateFormatSymbols::DateFormatSymbols(const Locale& locale, 273 const char *type, 274 UErrorCode& status) 275 : UObject() 276 { 277 initializeData(locale, type, status); 278 } 279 280 DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status) 281 : UObject() 282 { 283 initializeData(Locale::getDefault(), type, status, TRUE); 284 } 285 286 DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other) 287 : UObject(other) 288 { 289 copyData(other); 290 } 291 292 void 293 DateFormatSymbols::assignArray(UnicodeString*& dstArray, 294 int32_t& dstCount, 295 const UnicodeString* srcArray, 296 int32_t srcCount) 297 { 298 // assignArray() is only called by copyData(), which in turn implements the 299 // copy constructor and the assignment operator. 300 // All strings in a DateFormatSymbols object are created in one of the following 301 // three ways that all allow to safely use UnicodeString::fastCopyFrom(): 302 // - readonly-aliases from resource bundles 303 // - readonly-aliases or allocated strings from constants 304 // - safely cloned strings (with owned buffers) from setXYZ() functions 305 // 306 // Note that this is true for as long as DateFormatSymbols can be constructed 307 // only from a locale bundle or set via the cloning API, 308 // *and* for as long as all the strings are in *private* fields, preventing 309 // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()). 310 dstCount = srcCount; 311 dstArray = newUnicodeStringArray(srcCount); 312 if(dstArray != NULL) { 313 int32_t i; 314 for(i=0; i<srcCount; ++i) { 315 dstArray[i].fastCopyFrom(srcArray[i]); 316 } 317 } 318 } 319 320 /** 321 * Create a copy, in fZoneStrings, of the given zone strings array. The 322 * member variables fZoneStringsRowCount and fZoneStringsColCount should 323 * be set already by the caller. 324 */ 325 void 326 DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings) 327 { 328 int32_t row, col; 329 UBool failed = FALSE; 330 331 fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *)); 332 if (fZoneStrings != NULL) { 333 for (row=0; row<fZoneStringsRowCount; ++row) 334 { 335 fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount); 336 if (fZoneStrings[row] == NULL) { 337 failed = TRUE; 338 break; 339 } 340 for (col=0; col<fZoneStringsColCount; ++col) { 341 // fastCopyFrom() - see assignArray comments 342 fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]); 343 } 344 } 345 } 346 // If memory allocation failed, roll back and delete fZoneStrings 347 if (failed) { 348 for (int i = row; i >= 0; i--) { 349 delete[] fZoneStrings[i]; 350 } 351 uprv_free(fZoneStrings); 352 fZoneStrings = NULL; 353 } 354 } 355 356 /** 357 * Copy all of the other's data to this. 358 */ 359 void 360 DateFormatSymbols::copyData(const DateFormatSymbols& other) { 361 UErrorCode status = U_ZERO_ERROR; 362 U_LOCALE_BASED(locBased, *this); 363 locBased.setLocaleIDs( 364 other.getLocale(ULOC_VALID_LOCALE, status), 365 other.getLocale(ULOC_ACTUAL_LOCALE, status)); 366 assignArray(fEras, fErasCount, other.fEras, other.fErasCount); 367 assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount); 368 assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount); 369 assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount); 370 assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount); 371 assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount); 372 assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount); 373 assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount); 374 assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount); 375 assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount); 376 assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount); 377 assignArray(fShorterWeekdays, fShorterWeekdaysCount, other.fShorterWeekdays, other.fShorterWeekdaysCount); 378 assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount); 379 assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount); 380 assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount); 381 assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount); 382 assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount); 383 assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount); 384 assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount ); 385 fTimeSeparator.fastCopyFrom(other.fTimeSeparator); // fastCopyFrom() - see assignArray comments 386 assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount); 387 assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount); 388 assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount); 389 assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount); 390 if (other.fLeapMonthPatterns != NULL) { 391 assignArray(fLeapMonthPatterns, fLeapMonthPatternsCount, other.fLeapMonthPatterns, other.fLeapMonthPatternsCount); 392 } else { 393 fLeapMonthPatterns = NULL; 394 fLeapMonthPatternsCount = 0; 395 } 396 if (other.fShortYearNames != NULL) { 397 assignArray(fShortYearNames, fShortYearNamesCount, other.fShortYearNames, other.fShortYearNamesCount); 398 } else { 399 fShortYearNames = NULL; 400 fShortYearNamesCount = 0; 401 } 402 if (other.fShortZodiacNames != NULL) { 403 assignArray(fShortZodiacNames, fShortZodiacNamesCount, other.fShortZodiacNames, other.fShortZodiacNamesCount); 404 } else { 405 fShortZodiacNames = NULL; 406 fShortZodiacNamesCount = 0; 407 } 408 409 if (other.fZoneStrings != NULL) { 410 fZoneStringsColCount = other.fZoneStringsColCount; 411 fZoneStringsRowCount = other.fZoneStringsRowCount; 412 createZoneStrings((const UnicodeString**)other.fZoneStrings); 413 414 } else { 415 fZoneStrings = NULL; 416 fZoneStringsColCount = 0; 417 fZoneStringsRowCount = 0; 418 } 419 fZSFLocale = other.fZSFLocale; 420 // Other zone strings data is created on demand 421 fLocaleZoneStrings = NULL; 422 423 // fastCopyFrom() - see assignArray comments 424 fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars); 425 426 uprv_memcpy(fCapitalization, other.fCapitalization, sizeof(fCapitalization)); 427 } 428 429 /** 430 * Assignment operator. 431 */ 432 DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other) 433 { 434 dispose(); 435 copyData(other); 436 437 return *this; 438 } 439 440 DateFormatSymbols::~DateFormatSymbols() 441 { 442 dispose(); 443 } 444 445 void DateFormatSymbols::dispose() 446 { 447 if (fEras) delete[] fEras; 448 if (fEraNames) delete[] fEraNames; 449 if (fNarrowEras) delete[] fNarrowEras; 450 if (fMonths) delete[] fMonths; 451 if (fShortMonths) delete[] fShortMonths; 452 if (fNarrowMonths) delete[] fNarrowMonths; 453 if (fStandaloneMonths) delete[] fStandaloneMonths; 454 if (fStandaloneShortMonths) delete[] fStandaloneShortMonths; 455 if (fStandaloneNarrowMonths) delete[] fStandaloneNarrowMonths; 456 if (fWeekdays) delete[] fWeekdays; 457 if (fShortWeekdays) delete[] fShortWeekdays; 458 if (fShorterWeekdays) delete[] fShorterWeekdays; 459 if (fNarrowWeekdays) delete[] fNarrowWeekdays; 460 if (fStandaloneWeekdays) delete[] fStandaloneWeekdays; 461 if (fStandaloneShortWeekdays) delete[] fStandaloneShortWeekdays; 462 if (fStandaloneShorterWeekdays) delete[] fStandaloneShorterWeekdays; 463 if (fStandaloneNarrowWeekdays) delete[] fStandaloneNarrowWeekdays; 464 if (fAmPms) delete[] fAmPms; 465 if (fNarrowAmPms) delete[] fNarrowAmPms; 466 if (fQuarters) delete[] fQuarters; 467 if (fShortQuarters) delete[] fShortQuarters; 468 if (fStandaloneQuarters) delete[] fStandaloneQuarters; 469 if (fStandaloneShortQuarters) delete[] fStandaloneShortQuarters; 470 if (fLeapMonthPatterns) delete[] fLeapMonthPatterns; 471 if (fShortYearNames) delete[] fShortYearNames; 472 if (fShortZodiacNames) delete[] fShortZodiacNames; 473 474 disposeZoneStrings(); 475 } 476 477 void DateFormatSymbols::disposeZoneStrings() 478 { 479 if (fZoneStrings) { 480 for (int32_t row = 0; row < fZoneStringsRowCount; ++row) { 481 delete[] fZoneStrings[row]; 482 } 483 uprv_free(fZoneStrings); 484 } 485 if (fLocaleZoneStrings) { 486 for (int32_t row = 0; row < fZoneStringsRowCount; ++row) { 487 delete[] fLocaleZoneStrings[row]; 488 } 489 uprv_free(fLocaleZoneStrings); 490 } 491 492 fZoneStrings = NULL; 493 fLocaleZoneStrings = NULL; 494 fZoneStringsRowCount = 0; 495 fZoneStringsColCount = 0; 496 } 497 498 UBool 499 DateFormatSymbols::arrayCompare(const UnicodeString* array1, 500 const UnicodeString* array2, 501 int32_t count) 502 { 503 if (array1 == array2) return TRUE; 504 while (count>0) 505 { 506 --count; 507 if (array1[count] != array2[count]) return FALSE; 508 } 509 return TRUE; 510 } 511 512 UBool 513 DateFormatSymbols::operator==(const DateFormatSymbols& other) const 514 { 515 // First do cheap comparisons 516 if (this == &other) { 517 return TRUE; 518 } 519 if (fErasCount == other.fErasCount && 520 fEraNamesCount == other.fEraNamesCount && 521 fNarrowErasCount == other.fNarrowErasCount && 522 fMonthsCount == other.fMonthsCount && 523 fShortMonthsCount == other.fShortMonthsCount && 524 fNarrowMonthsCount == other.fNarrowMonthsCount && 525 fStandaloneMonthsCount == other.fStandaloneMonthsCount && 526 fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount && 527 fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount && 528 fWeekdaysCount == other.fWeekdaysCount && 529 fShortWeekdaysCount == other.fShortWeekdaysCount && 530 fShorterWeekdaysCount == other.fShorterWeekdaysCount && 531 fNarrowWeekdaysCount == other.fNarrowWeekdaysCount && 532 fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount && 533 fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount && 534 fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount && 535 fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount && 536 fAmPmsCount == other.fAmPmsCount && 537 fNarrowAmPmsCount == other.fNarrowAmPmsCount && 538 fQuartersCount == other.fQuartersCount && 539 fShortQuartersCount == other.fShortQuartersCount && 540 fStandaloneQuartersCount == other.fStandaloneQuartersCount && 541 fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount && 542 fLeapMonthPatternsCount == other.fLeapMonthPatternsCount && 543 fShortYearNamesCount == other.fShortYearNamesCount && 544 fShortZodiacNamesCount == other.fShortZodiacNamesCount && 545 (uprv_memcmp(fCapitalization, other.fCapitalization, sizeof(fCapitalization))==0)) 546 { 547 // Now compare the arrays themselves 548 if (arrayCompare(fEras, other.fEras, fErasCount) && 549 arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) && 550 arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) && 551 arrayCompare(fMonths, other.fMonths, fMonthsCount) && 552 arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) && 553 arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) && 554 arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) && 555 arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) && 556 arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) && 557 arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) && 558 arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) && 559 arrayCompare(fShorterWeekdays, other.fShorterWeekdays, fShorterWeekdaysCount) && 560 arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) && 561 arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) && 562 arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) && 563 arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) && 564 arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) && 565 arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) && 566 arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) && 567 fTimeSeparator == other.fTimeSeparator && 568 arrayCompare(fQuarters, other.fQuarters, fQuartersCount) && 569 arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) && 570 arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) && 571 arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount) && 572 arrayCompare(fLeapMonthPatterns, other.fLeapMonthPatterns, fLeapMonthPatternsCount) && 573 arrayCompare(fShortYearNames, other.fShortYearNames, fShortYearNamesCount) && 574 arrayCompare(fShortZodiacNames, other.fShortZodiacNames, fShortZodiacNamesCount)) 575 { 576 // Compare the contents of fZoneStrings 577 if (fZoneStrings == NULL && other.fZoneStrings == NULL) { 578 if (fZSFLocale == other.fZSFLocale) { 579 return TRUE; 580 } 581 } else if (fZoneStrings != NULL && other.fZoneStrings != NULL) { 582 if (fZoneStringsRowCount == other.fZoneStringsRowCount 583 && fZoneStringsColCount == other.fZoneStringsColCount) { 584 UBool cmpres = TRUE; 585 for (int32_t i = 0; (i < fZoneStringsRowCount) && cmpres; i++) { 586 cmpres = arrayCompare(fZoneStrings[i], other.fZoneStrings[i], fZoneStringsColCount); 587 } 588 return cmpres; 589 } 590 } 591 return FALSE; 592 } 593 } 594 return FALSE; 595 } 596 597 //------------------------------------------------------ 598 599 const UnicodeString* 600 DateFormatSymbols::getEras(int32_t &count) const 601 { 602 count = fErasCount; 603 return fEras; 604 } 605 606 const UnicodeString* 607 DateFormatSymbols::getEraNames(int32_t &count) const 608 { 609 count = fEraNamesCount; 610 return fEraNames; 611 } 612 613 const UnicodeString* 614 DateFormatSymbols::getNarrowEras(int32_t &count) const 615 { 616 count = fNarrowErasCount; 617 return fNarrowEras; 618 } 619 620 const UnicodeString* 621 DateFormatSymbols::getMonths(int32_t &count) const 622 { 623 count = fMonthsCount; 624 return fMonths; 625 } 626 627 const UnicodeString* 628 DateFormatSymbols::getShortMonths(int32_t &count) const 629 { 630 count = fShortMonthsCount; 631 return fShortMonths; 632 } 633 634 const UnicodeString* 635 DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const 636 { 637 UnicodeString *returnValue = NULL; 638 639 switch (context) { 640 case FORMAT : 641 switch(width) { 642 case WIDE : 643 count = fMonthsCount; 644 returnValue = fMonths; 645 break; 646 case ABBREVIATED : 647 case SHORT : // no month data for this, defaults to ABBREVIATED 648 count = fShortMonthsCount; 649 returnValue = fShortMonths; 650 break; 651 case NARROW : 652 count = fNarrowMonthsCount; 653 returnValue = fNarrowMonths; 654 break; 655 case DT_WIDTH_COUNT : 656 break; 657 } 658 break; 659 case STANDALONE : 660 switch(width) { 661 case WIDE : 662 count = fStandaloneMonthsCount; 663 returnValue = fStandaloneMonths; 664 break; 665 case ABBREVIATED : 666 case SHORT : // no month data for this, defaults to ABBREVIATED 667 count = fStandaloneShortMonthsCount; 668 returnValue = fStandaloneShortMonths; 669 break; 670 case NARROW : 671 count = fStandaloneNarrowMonthsCount; 672 returnValue = fStandaloneNarrowMonths; 673 break; 674 case DT_WIDTH_COUNT : 675 break; 676 } 677 break; 678 case DT_CONTEXT_COUNT : 679 break; 680 } 681 return returnValue; 682 } 683 684 const UnicodeString* 685 DateFormatSymbols::getWeekdays(int32_t &count) const 686 { 687 count = fWeekdaysCount; 688 return fWeekdays; 689 } 690 691 const UnicodeString* 692 DateFormatSymbols::getShortWeekdays(int32_t &count) const 693 { 694 count = fShortWeekdaysCount; 695 return fShortWeekdays; 696 } 697 698 const UnicodeString* 699 DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const 700 { 701 UnicodeString *returnValue = NULL; 702 switch (context) { 703 case FORMAT : 704 switch(width) { 705 case WIDE : 706 count = fWeekdaysCount; 707 returnValue = fWeekdays; 708 break; 709 case ABBREVIATED : 710 count = fShortWeekdaysCount; 711 returnValue = fShortWeekdays; 712 break; 713 case SHORT : 714 count = fShorterWeekdaysCount; 715 returnValue = fShorterWeekdays; 716 break; 717 case NARROW : 718 count = fNarrowWeekdaysCount; 719 returnValue = fNarrowWeekdays; 720 break; 721 case DT_WIDTH_COUNT : 722 break; 723 } 724 break; 725 case STANDALONE : 726 switch(width) { 727 case WIDE : 728 count = fStandaloneWeekdaysCount; 729 returnValue = fStandaloneWeekdays; 730 break; 731 case ABBREVIATED : 732 count = fStandaloneShortWeekdaysCount; 733 returnValue = fStandaloneShortWeekdays; 734 break; 735 case SHORT : 736 count = fStandaloneShorterWeekdaysCount; 737 returnValue = fStandaloneShorterWeekdays; 738 break; 739 case NARROW : 740 count = fStandaloneNarrowWeekdaysCount; 741 returnValue = fStandaloneNarrowWeekdays; 742 break; 743 case DT_WIDTH_COUNT : 744 break; 745 } 746 break; 747 case DT_CONTEXT_COUNT : 748 break; 749 } 750 return returnValue; 751 } 752 753 const UnicodeString* 754 DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const 755 { 756 UnicodeString *returnValue = NULL; 757 758 switch (context) { 759 case FORMAT : 760 switch(width) { 761 case WIDE : 762 count = fQuartersCount; 763 returnValue = fQuarters; 764 break; 765 case ABBREVIATED : 766 case SHORT : // no quarter data for this, defaults to ABBREVIATED 767 count = fShortQuartersCount; 768 returnValue = fShortQuarters; 769 break; 770 case NARROW : 771 count = 0; 772 returnValue = NULL; 773 break; 774 case DT_WIDTH_COUNT : 775 break; 776 } 777 break; 778 case STANDALONE : 779 switch(width) { 780 case WIDE : 781 count = fStandaloneQuartersCount; 782 returnValue = fStandaloneQuarters; 783 break; 784 case ABBREVIATED : 785 case SHORT : // no quarter data for this, defaults to ABBREVIATED 786 count = fStandaloneShortQuartersCount; 787 returnValue = fStandaloneShortQuarters; 788 break; 789 case NARROW : 790 count = 0; 791 returnValue = NULL; 792 break; 793 case DT_WIDTH_COUNT : 794 break; 795 } 796 break; 797 case DT_CONTEXT_COUNT : 798 break; 799 } 800 return returnValue; 801 } 802 803 UnicodeString& 804 DateFormatSymbols::getTimeSeparatorString(UnicodeString& result) const 805 { 806 // fastCopyFrom() - see assignArray comments 807 return result.fastCopyFrom(fTimeSeparator); 808 } 809 810 const UnicodeString* 811 DateFormatSymbols::getAmPmStrings(int32_t &count) const 812 { 813 count = fAmPmsCount; 814 return fAmPms; 815 } 816 817 const UnicodeString* 818 DateFormatSymbols::getLeapMonthPatterns(int32_t &count) const 819 { 820 count = fLeapMonthPatternsCount; 821 return fLeapMonthPatterns; 822 } 823 824 const UnicodeString* 825 DateFormatSymbols::getYearNames(int32_t& count, 826 DtContextType /*ignored*/, DtWidthType /*ignored*/) const 827 { 828 count = fShortYearNamesCount; 829 return fShortYearNames; 830 } 831 832 void 833 DateFormatSymbols::setYearNames(const UnicodeString* yearNames, int32_t count, 834 DtContextType context, DtWidthType width) 835 { 836 if (context == FORMAT && width == ABBREVIATED) { 837 if (fShortYearNames) { 838 delete[] fShortYearNames; 839 } 840 fShortYearNames = newUnicodeStringArray(count); 841 uprv_arrayCopy(yearNames, fShortYearNames, count); 842 fShortYearNamesCount = count; 843 } 844 } 845 846 const UnicodeString* 847 DateFormatSymbols::getZodiacNames(int32_t& count, 848 DtContextType /*ignored*/, DtWidthType /*ignored*/) const 849 { 850 count = fShortZodiacNamesCount; 851 return fShortZodiacNames; 852 } 853 854 void 855 DateFormatSymbols::setZodiacNames(const UnicodeString* zodiacNames, int32_t count, 856 DtContextType context, DtWidthType width) 857 { 858 if (context == FORMAT && width == ABBREVIATED) { 859 if (fShortZodiacNames) { 860 delete[] fShortZodiacNames; 861 } 862 fShortZodiacNames = newUnicodeStringArray(count); 863 uprv_arrayCopy(zodiacNames, fShortZodiacNames, count); 864 fShortZodiacNamesCount = count; 865 } 866 } 867 868 //------------------------------------------------------ 869 870 void 871 DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count) 872 { 873 // delete the old list if we own it 874 if (fEras) 875 delete[] fEras; 876 877 // we always own the new list, which we create here (we duplicate rather 878 // than adopting the list passed in) 879 fEras = newUnicodeStringArray(count); 880 uprv_arrayCopy(erasArray,fEras, count); 881 fErasCount = count; 882 } 883 884 void 885 DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count) 886 { 887 // delete the old list if we own it 888 if (fEraNames) 889 delete[] fEraNames; 890 891 // we always own the new list, which we create here (we duplicate rather 892 // than adopting the list passed in) 893 fEraNames = newUnicodeStringArray(count); 894 uprv_arrayCopy(eraNamesArray,fEraNames, count); 895 fEraNamesCount = count; 896 } 897 898 void 899 DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count) 900 { 901 // delete the old list if we own it 902 if (fNarrowEras) 903 delete[] fNarrowEras; 904 905 // we always own the new list, which we create here (we duplicate rather 906 // than adopting the list passed in) 907 fNarrowEras = newUnicodeStringArray(count); 908 uprv_arrayCopy(narrowErasArray,fNarrowEras, count); 909 fNarrowErasCount = count; 910 } 911 912 void 913 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count) 914 { 915 // delete the old list if we own it 916 if (fMonths) 917 delete[] fMonths; 918 919 // we always own the new list, which we create here (we duplicate rather 920 // than adopting the list passed in) 921 fMonths = newUnicodeStringArray(count); 922 uprv_arrayCopy( monthsArray,fMonths,count); 923 fMonthsCount = count; 924 } 925 926 void 927 DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count) 928 { 929 // delete the old list if we own it 930 if (fShortMonths) 931 delete[] fShortMonths; 932 933 // we always own the new list, which we create here (we duplicate rather 934 // than adopting the list passed in) 935 fShortMonths = newUnicodeStringArray(count); 936 uprv_arrayCopy(shortMonthsArray,fShortMonths, count); 937 fShortMonthsCount = count; 938 } 939 940 void 941 DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width) 942 { 943 // delete the old list if we own it 944 // we always own the new list, which we create here (we duplicate rather 945 // than adopting the list passed in) 946 947 switch (context) { 948 case FORMAT : 949 switch (width) { 950 case WIDE : 951 if (fMonths) 952 delete[] fMonths; 953 fMonths = newUnicodeStringArray(count); 954 uprv_arrayCopy( monthsArray,fMonths,count); 955 fMonthsCount = count; 956 break; 957 case ABBREVIATED : 958 if (fShortMonths) 959 delete[] fShortMonths; 960 fShortMonths = newUnicodeStringArray(count); 961 uprv_arrayCopy( monthsArray,fShortMonths,count); 962 fShortMonthsCount = count; 963 break; 964 case NARROW : 965 if (fNarrowMonths) 966 delete[] fNarrowMonths; 967 fNarrowMonths = newUnicodeStringArray(count); 968 uprv_arrayCopy( monthsArray,fNarrowMonths,count); 969 fNarrowMonthsCount = count; 970 break; 971 default : 972 break; 973 } 974 break; 975 case STANDALONE : 976 switch (width) { 977 case WIDE : 978 if (fStandaloneMonths) 979 delete[] fStandaloneMonths; 980 fStandaloneMonths = newUnicodeStringArray(count); 981 uprv_arrayCopy( monthsArray,fStandaloneMonths,count); 982 fStandaloneMonthsCount = count; 983 break; 984 case ABBREVIATED : 985 if (fStandaloneShortMonths) 986 delete[] fStandaloneShortMonths; 987 fStandaloneShortMonths = newUnicodeStringArray(count); 988 uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count); 989 fStandaloneShortMonthsCount = count; 990 break; 991 case NARROW : 992 if (fStandaloneNarrowMonths) 993 delete[] fStandaloneNarrowMonths; 994 fStandaloneNarrowMonths = newUnicodeStringArray(count); 995 uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count); 996 fStandaloneNarrowMonthsCount = count; 997 break; 998 default : 999 break; 1000 } 1001 break; 1002 case DT_CONTEXT_COUNT : 1003 break; 1004 } 1005 } 1006 1007 void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count) 1008 { 1009 // delete the old list if we own it 1010 if (fWeekdays) 1011 delete[] fWeekdays; 1012 1013 // we always own the new list, which we create here (we duplicate rather 1014 // than adopting the list passed in) 1015 fWeekdays = newUnicodeStringArray(count); 1016 uprv_arrayCopy(weekdaysArray,fWeekdays,count); 1017 fWeekdaysCount = count; 1018 } 1019 1020 void 1021 DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count) 1022 { 1023 // delete the old list if we own it 1024 if (fShortWeekdays) 1025 delete[] fShortWeekdays; 1026 1027 // we always own the new list, which we create here (we duplicate rather 1028 // than adopting the list passed in) 1029 fShortWeekdays = newUnicodeStringArray(count); 1030 uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count); 1031 fShortWeekdaysCount = count; 1032 } 1033 1034 void 1035 DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width) 1036 { 1037 // delete the old list if we own it 1038 // we always own the new list, which we create here (we duplicate rather 1039 // than adopting the list passed in) 1040 1041 switch (context) { 1042 case FORMAT : 1043 switch (width) { 1044 case WIDE : 1045 if (fWeekdays) 1046 delete[] fWeekdays; 1047 fWeekdays = newUnicodeStringArray(count); 1048 uprv_arrayCopy(weekdaysArray, fWeekdays, count); 1049 fWeekdaysCount = count; 1050 break; 1051 case ABBREVIATED : 1052 if (fShortWeekdays) 1053 delete[] fShortWeekdays; 1054 fShortWeekdays = newUnicodeStringArray(count); 1055 uprv_arrayCopy(weekdaysArray, fShortWeekdays, count); 1056 fShortWeekdaysCount = count; 1057 break; 1058 case SHORT : 1059 if (fShorterWeekdays) 1060 delete[] fShorterWeekdays; 1061 fShorterWeekdays = newUnicodeStringArray(count); 1062 uprv_arrayCopy(weekdaysArray, fShorterWeekdays, count); 1063 fShorterWeekdaysCount = count; 1064 break; 1065 case NARROW : 1066 if (fNarrowWeekdays) 1067 delete[] fNarrowWeekdays; 1068 fNarrowWeekdays = newUnicodeStringArray(count); 1069 uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count); 1070 fNarrowWeekdaysCount = count; 1071 break; 1072 case DT_WIDTH_COUNT : 1073 break; 1074 } 1075 break; 1076 case STANDALONE : 1077 switch (width) { 1078 case WIDE : 1079 if (fStandaloneWeekdays) 1080 delete[] fStandaloneWeekdays; 1081 fStandaloneWeekdays = newUnicodeStringArray(count); 1082 uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count); 1083 fStandaloneWeekdaysCount = count; 1084 break; 1085 case ABBREVIATED : 1086 if (fStandaloneShortWeekdays) 1087 delete[] fStandaloneShortWeekdays; 1088 fStandaloneShortWeekdays = newUnicodeStringArray(count); 1089 uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count); 1090 fStandaloneShortWeekdaysCount = count; 1091 break; 1092 case SHORT : 1093 if (fStandaloneShorterWeekdays) 1094 delete[] fStandaloneShorterWeekdays; 1095 fStandaloneShorterWeekdays = newUnicodeStringArray(count); 1096 uprv_arrayCopy(weekdaysArray, fStandaloneShorterWeekdays, count); 1097 fStandaloneShorterWeekdaysCount = count; 1098 break; 1099 case NARROW : 1100 if (fStandaloneNarrowWeekdays) 1101 delete[] fStandaloneNarrowWeekdays; 1102 fStandaloneNarrowWeekdays = newUnicodeStringArray(count); 1103 uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count); 1104 fStandaloneNarrowWeekdaysCount = count; 1105 break; 1106 case DT_WIDTH_COUNT : 1107 break; 1108 } 1109 break; 1110 case DT_CONTEXT_COUNT : 1111 break; 1112 } 1113 } 1114 1115 void 1116 DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width) 1117 { 1118 // delete the old list if we own it 1119 // we always own the new list, which we create here (we duplicate rather 1120 // than adopting the list passed in) 1121 1122 switch (context) { 1123 case FORMAT : 1124 switch (width) { 1125 case WIDE : 1126 if (fQuarters) 1127 delete[] fQuarters; 1128 fQuarters = newUnicodeStringArray(count); 1129 uprv_arrayCopy( quartersArray,fQuarters,count); 1130 fQuartersCount = count; 1131 break; 1132 case ABBREVIATED : 1133 if (fShortQuarters) 1134 delete[] fShortQuarters; 1135 fShortQuarters = newUnicodeStringArray(count); 1136 uprv_arrayCopy( quartersArray,fShortQuarters,count); 1137 fShortQuartersCount = count; 1138 break; 1139 case NARROW : 1140 /* 1141 if (fNarrowQuarters) 1142 delete[] fNarrowQuarters; 1143 fNarrowQuarters = newUnicodeStringArray(count); 1144 uprv_arrayCopy( quartersArray,fNarrowQuarters,count); 1145 fNarrowQuartersCount = count; 1146 */ 1147 break; 1148 default : 1149 break; 1150 } 1151 break; 1152 case STANDALONE : 1153 switch (width) { 1154 case WIDE : 1155 if (fStandaloneQuarters) 1156 delete[] fStandaloneQuarters; 1157 fStandaloneQuarters = newUnicodeStringArray(count); 1158 uprv_arrayCopy( quartersArray,fStandaloneQuarters,count); 1159 fStandaloneQuartersCount = count; 1160 break; 1161 case ABBREVIATED : 1162 if (fStandaloneShortQuarters) 1163 delete[] fStandaloneShortQuarters; 1164 fStandaloneShortQuarters = newUnicodeStringArray(count); 1165 uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count); 1166 fStandaloneShortQuartersCount = count; 1167 break; 1168 case NARROW : 1169 /* 1170 if (fStandaloneNarrowQuarters) 1171 delete[] fStandaloneNarrowQuarters; 1172 fStandaloneNarrowQuarters = newUnicodeStringArray(count); 1173 uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count); 1174 fStandaloneNarrowQuartersCount = count; 1175 */ 1176 break; 1177 default : 1178 break; 1179 } 1180 break; 1181 case DT_CONTEXT_COUNT : 1182 break; 1183 } 1184 } 1185 1186 void 1187 DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count) 1188 { 1189 // delete the old list if we own it 1190 if (fAmPms) delete[] fAmPms; 1191 1192 // we always own the new list, which we create here (we duplicate rather 1193 // than adopting the list passed in) 1194 fAmPms = newUnicodeStringArray(count); 1195 uprv_arrayCopy(amPmsArray,fAmPms,count); 1196 fAmPmsCount = count; 1197 } 1198 1199 void 1200 DateFormatSymbols::setTimeSeparatorString(const UnicodeString& newTimeSeparator) 1201 { 1202 fTimeSeparator = newTimeSeparator; 1203 } 1204 1205 const UnicodeString** 1206 DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const 1207 { 1208 const UnicodeString **result = NULL; 1209 1210 umtx_lock(&LOCK); 1211 if (fZoneStrings == NULL) { 1212 if (fLocaleZoneStrings == NULL) { 1213 ((DateFormatSymbols*)this)->initZoneStringsArray(); 1214 } 1215 result = (const UnicodeString**)fLocaleZoneStrings; 1216 } else { 1217 result = (const UnicodeString**)fZoneStrings; 1218 } 1219 rowCount = fZoneStringsRowCount; 1220 columnCount = fZoneStringsColCount; 1221 umtx_unlock(&LOCK); 1222 1223 return result; 1224 } 1225 1226 // For now, we include all zones 1227 #define ZONE_SET UCAL_ZONE_TYPE_ANY 1228 1229 // This code must be called within a synchronized block 1230 void 1231 DateFormatSymbols::initZoneStringsArray(void) { 1232 if (fZoneStrings != NULL || fLocaleZoneStrings != NULL) { 1233 return; 1234 } 1235 1236 UErrorCode status = U_ZERO_ERROR; 1237 1238 StringEnumeration *tzids = NULL; 1239 UnicodeString ** zarray = NULL; 1240 TimeZoneNames *tzNames = NULL; 1241 int32_t rows = 0; 1242 1243 do { // dummy do-while 1244 1245 tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status); 1246 rows = tzids->count(status); 1247 if (U_FAILURE(status)) { 1248 break; 1249 } 1250 1251 // Allocate array 1252 int32_t size = rows * sizeof(UnicodeString*); 1253 zarray = (UnicodeString**)uprv_malloc(size); 1254 if (zarray == NULL) { 1255 status = U_MEMORY_ALLOCATION_ERROR; 1256 break; 1257 } 1258 uprv_memset(zarray, 0, size); 1259 1260 tzNames = TimeZoneNames::createInstance(fZSFLocale, status); 1261 1262 const UnicodeString *tzid; 1263 int32_t i = 0; 1264 UDate now = Calendar::getNow(); 1265 UnicodeString tzDispName; 1266 1267 while ((tzid = tzids->snext(status))) { 1268 if (U_FAILURE(status)) { 1269 break; 1270 } 1271 1272 zarray[i] = new UnicodeString[5]; 1273 if (zarray[i] == NULL) { 1274 status = U_MEMORY_ALLOCATION_ERROR; 1275 break; 1276 } 1277 1278 zarray[i][0].setTo(*tzid); 1279 zarray[i][1].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_STANDARD, now, tzDispName)); 1280 zarray[i][2].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_STANDARD, now, tzDispName)); 1281 zarray[i][3].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_DAYLIGHT, now, tzDispName)); 1282 zarray[i][4].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_DAYLIGHT, now, tzDispName)); 1283 i++; 1284 } 1285 1286 } while (FALSE); 1287 1288 if (U_FAILURE(status)) { 1289 if (zarray) { 1290 for (int32_t i = 0; i < rows; i++) { 1291 if (zarray[i]) { 1292 delete[] zarray[i]; 1293 } 1294 } 1295 uprv_free(zarray); 1296 } 1297 } 1298 1299 if (tzNames) { 1300 delete tzNames; 1301 } 1302 if (tzids) { 1303 delete tzids; 1304 } 1305 1306 fLocaleZoneStrings = zarray; 1307 fZoneStringsRowCount = rows; 1308 fZoneStringsColCount = 5; 1309 } 1310 1311 void 1312 DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount) 1313 { 1314 // since deleting a 2-d array is a pain in the butt, we offload that task to 1315 // a separate function 1316 disposeZoneStrings(); 1317 // we always own the new list, which we create here (we duplicate rather 1318 // than adopting the list passed in) 1319 fZoneStringsRowCount = rowCount; 1320 fZoneStringsColCount = columnCount; 1321 createZoneStrings((const UnicodeString**)strings); 1322 } 1323 1324 //------------------------------------------------------ 1325 1326 const UChar * U_EXPORT2 1327 DateFormatSymbols::getPatternUChars(void) 1328 { 1329 return gPatternChars; 1330 } 1331 1332 UDateFormatField U_EXPORT2 1333 DateFormatSymbols::getPatternCharIndex(UChar c) { 1334 const UChar *p = u_strchr(gPatternChars, c); 1335 if (p == NULL) { 1336 return UDAT_FIELD_COUNT; 1337 } else { 1338 return static_cast<UDateFormatField>(p - gPatternChars); 1339 } 1340 } 1341 1342 static const uint64_t kNumericFieldsAlways = 1343 ((uint64_t)1 << UDAT_YEAR_FIELD) | // y 1344 ((uint64_t)1 << UDAT_DATE_FIELD) | // d 1345 ((uint64_t)1 << UDAT_HOUR_OF_DAY1_FIELD) | // k 1346 ((uint64_t)1 << UDAT_HOUR_OF_DAY0_FIELD) | // H 1347 ((uint64_t)1 << UDAT_MINUTE_FIELD) | // m 1348 ((uint64_t)1 << UDAT_SECOND_FIELD) | // s 1349 ((uint64_t)1 << UDAT_FRACTIONAL_SECOND_FIELD) | // S 1350 ((uint64_t)1 << UDAT_DAY_OF_YEAR_FIELD) | // D 1351 ((uint64_t)1 << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) | // F 1352 ((uint64_t)1 << UDAT_WEEK_OF_YEAR_FIELD) | // w 1353 ((uint64_t)1 << UDAT_WEEK_OF_MONTH_FIELD) | // W 1354 ((uint64_t)1 << UDAT_HOUR1_FIELD) | // h 1355 ((uint64_t)1 << UDAT_HOUR0_FIELD) | // K 1356 ((uint64_t)1 << UDAT_YEAR_WOY_FIELD) | // Y 1357 ((uint64_t)1 << UDAT_EXTENDED_YEAR_FIELD) | // u 1358 ((uint64_t)1 << UDAT_JULIAN_DAY_FIELD) | // g 1359 ((uint64_t)1 << UDAT_MILLISECONDS_IN_DAY_FIELD) | // A 1360 ((uint64_t)1 << UDAT_RELATED_YEAR_FIELD); // r 1361 1362 static const uint64_t kNumericFieldsForCount12 = 1363 ((uint64_t)1 << UDAT_MONTH_FIELD) | // M or MM 1364 ((uint64_t)1 << UDAT_DOW_LOCAL_FIELD) | // e or ee 1365 ((uint64_t)1 << UDAT_STANDALONE_DAY_FIELD) | // c or cc 1366 ((uint64_t)1 << UDAT_STANDALONE_MONTH_FIELD) | // L or LL 1367 ((uint64_t)1 << UDAT_QUARTER_FIELD) | // Q or QQ 1368 ((uint64_t)1 << UDAT_STANDALONE_QUARTER_FIELD); // q or qq 1369 1370 UBool U_EXPORT2 1371 DateFormatSymbols::isNumericField(UDateFormatField f, int32_t count) { 1372 if (f == UDAT_FIELD_COUNT) { 1373 return FALSE; 1374 } 1375 uint64_t flag = ((uint64_t)1 << f); 1376 return ((kNumericFieldsAlways & flag) != 0 || ((kNumericFieldsForCount12 & flag) != 0 && count < 3)); 1377 } 1378 1379 UBool U_EXPORT2 1380 DateFormatSymbols::isNumericPatternChar(UChar c, int32_t count) { 1381 return isNumericField(getPatternCharIndex(c), count); 1382 } 1383 1384 //------------------------------------------------------ 1385 1386 UnicodeString& 1387 DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const 1388 { 1389 // fastCopyFrom() - see assignArray comments 1390 return result.fastCopyFrom(fLocalPatternChars); 1391 } 1392 1393 //------------------------------------------------------ 1394 1395 void 1396 DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars) 1397 { 1398 fLocalPatternChars = newLocalPatternChars; 1399 } 1400 1401 //------------------------------------------------------ 1402 1403 static void 1404 initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) { 1405 if (U_SUCCESS(status)) { 1406 int32_t strLen = 0; 1407 length = ures_getSize(data); 1408 *field = newUnicodeStringArray(length); 1409 if (*field) { 1410 for(int32_t i = 0; i<length; i++) { 1411 const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status); 1412 // setTo() - see assignArray comments 1413 (*(field)+i)->setTo(TRUE, resStr, strLen); 1414 } 1415 } 1416 else { 1417 length = 0; 1418 status = U_MEMORY_ALLOCATION_ERROR; 1419 } 1420 } 1421 } 1422 1423 static void 1424 initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) { 1425 if (U_SUCCESS(status)) { 1426 length = numStr; 1427 *field = newUnicodeStringArray((size_t)numStr); 1428 if (*field) { 1429 for(int32_t i = 0; i<length; i++) { 1430 // readonly aliases - all "data" strings are constant 1431 // -1 as length for variable-length strings (gLastResortDayNames[0] is empty) 1432 (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1); 1433 } 1434 } 1435 else { 1436 length = 0; 1437 status = U_MEMORY_ALLOCATION_ERROR; 1438 } 1439 } 1440 } 1441 1442 static void 1443 initLeapMonthPattern(UnicodeString *field, int32_t index, const UResourceBundle *data, UErrorCode &status) { 1444 field[index].remove(); 1445 if (U_SUCCESS(status)) { 1446 int32_t strLen = 0; 1447 const UChar *resStr = ures_getStringByKey(data, gNamesLeapTag, &strLen, &status); 1448 if (U_SUCCESS(status)) { 1449 field[index].setTo(TRUE, resStr, strLen); 1450 } 1451 } 1452 status = U_ZERO_ERROR; 1453 } 1454 1455 typedef struct { 1456 const char * usageTypeName; 1457 DateFormatSymbols::ECapitalizationContextUsageType usageTypeEnumValue; 1458 } ContextUsageTypeNameToEnumValue; 1459 1460 static const ContextUsageTypeNameToEnumValue contextUsageTypeMap[] = { 1461 // Entries must be sorted by usageTypeName; entry with NULL name terminates list. 1462 { "day-format-except-narrow", DateFormatSymbols::kCapContextUsageDayFormat }, 1463 { "day-narrow", DateFormatSymbols::kCapContextUsageDayNarrow }, 1464 { "day-standalone-except-narrow", DateFormatSymbols::kCapContextUsageDayStandalone }, 1465 { "era-abbr", DateFormatSymbols::kCapContextUsageEraAbbrev }, 1466 { "era-name", DateFormatSymbols::kCapContextUsageEraWide }, 1467 { "era-narrow", DateFormatSymbols::kCapContextUsageEraNarrow }, 1468 { "metazone-long", DateFormatSymbols::kCapContextUsageMetazoneLong }, 1469 { "metazone-short", DateFormatSymbols::kCapContextUsageMetazoneShort }, 1470 { "month-format-except-narrow", DateFormatSymbols::kCapContextUsageMonthFormat }, 1471 { "month-narrow", DateFormatSymbols::kCapContextUsageMonthNarrow }, 1472 { "month-standalone-except-narrow", DateFormatSymbols::kCapContextUsageMonthStandalone }, 1473 { "zone-long", DateFormatSymbols::kCapContextUsageZoneLong }, 1474 { "zone-short", DateFormatSymbols::kCapContextUsageZoneShort }, 1475 { NULL, (DateFormatSymbols::ECapitalizationContextUsageType)0 }, 1476 }; 1477 1478 void 1479 DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData) 1480 { 1481 int32_t i; 1482 int32_t len = 0; 1483 const UChar *resStr; 1484 /* In case something goes wrong, initialize all of the data to NULL. */ 1485 fEras = NULL; 1486 fErasCount = 0; 1487 fEraNames = NULL; 1488 fEraNamesCount = 0; 1489 fNarrowEras = NULL; 1490 fNarrowErasCount = 0; 1491 fMonths = NULL; 1492 fMonthsCount=0; 1493 fShortMonths = NULL; 1494 fShortMonthsCount=0; 1495 fNarrowMonths = NULL; 1496 fNarrowMonthsCount=0; 1497 fStandaloneMonths = NULL; 1498 fStandaloneMonthsCount=0; 1499 fStandaloneShortMonths = NULL; 1500 fStandaloneShortMonthsCount=0; 1501 fStandaloneNarrowMonths = NULL; 1502 fStandaloneNarrowMonthsCount=0; 1503 fWeekdays = NULL; 1504 fWeekdaysCount=0; 1505 fShortWeekdays = NULL; 1506 fShortWeekdaysCount=0; 1507 fShorterWeekdays = NULL; 1508 fShorterWeekdaysCount=0; 1509 fNarrowWeekdays = NULL; 1510 fNarrowWeekdaysCount=0; 1511 fStandaloneWeekdays = NULL; 1512 fStandaloneWeekdaysCount=0; 1513 fStandaloneShortWeekdays = NULL; 1514 fStandaloneShortWeekdaysCount=0; 1515 fStandaloneShorterWeekdays = NULL; 1516 fStandaloneShorterWeekdaysCount=0; 1517 fStandaloneNarrowWeekdays = NULL; 1518 fStandaloneNarrowWeekdaysCount=0; 1519 fAmPms = NULL; 1520 fAmPmsCount=0; 1521 fNarrowAmPms = NULL; 1522 fNarrowAmPmsCount=0; 1523 fTimeSeparator.setToBogus(); 1524 fQuarters = NULL; 1525 fQuartersCount = 0; 1526 fShortQuarters = NULL; 1527 fShortQuartersCount = 0; 1528 fStandaloneQuarters = NULL; 1529 fStandaloneQuartersCount = 0; 1530 fStandaloneShortQuarters = NULL; 1531 fStandaloneShortQuartersCount = 0; 1532 fLeapMonthPatterns = NULL; 1533 fLeapMonthPatternsCount = 0; 1534 fShortYearNames = NULL; 1535 fShortYearNamesCount = 0; 1536 fShortZodiacNames = NULL; 1537 fShortZodiacNamesCount = 0; 1538 fZoneStringsRowCount = 0; 1539 fZoneStringsColCount = 0; 1540 fZoneStrings = NULL; 1541 fLocaleZoneStrings = NULL; 1542 uprv_memset(fCapitalization, 0, sizeof(fCapitalization)); 1543 1544 // We need to preserve the requested locale for 1545 // lazy ZoneStringFormat instantiation. ZoneStringFormat 1546 // is region sensitive, thus, bundle locale bundle's locale 1547 // is not sufficient. 1548 fZSFLocale = locale; 1549 1550 if (U_FAILURE(status)) return; 1551 1552 /** 1553 * Retrieve the string arrays we need from the resource bundle file. 1554 * We cast away const here, but that's okay; we won't delete any of 1555 * these. 1556 */ 1557 CalendarData calData(locale, type, status); 1558 1559 // load the first data item 1560 UResourceBundle *erasMain = calData.getByKey(gErasTag, status); 1561 UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); 1562 UErrorCode oldStatus = status; 1563 UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status); 1564 if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3 1565 status = oldStatus; 1566 eraNames = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); 1567 } 1568 // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too 1569 oldStatus = status; 1570 UResourceBundle *narrowEras = ures_getByKeyWithFallback(erasMain, gNamesNarrowTag, NULL, &status); 1571 if ( status == U_MISSING_RESOURCE_ERROR ) { 1572 status = oldStatus; 1573 narrowEras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); 1574 } 1575 1576 UErrorCode tempStatus = U_ZERO_ERROR; 1577 UResourceBundle *monthPatterns = calData.getByKey(gMonthPatternsTag, tempStatus); 1578 if (U_SUCCESS(tempStatus) && monthPatterns != NULL) { 1579 fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount); 1580 if (fLeapMonthPatterns) { 1581 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calData.getByKey2(gMonthPatternsTag, gNamesWideTag, tempStatus), tempStatus); 1582 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calData.getByKey2(gMonthPatternsTag, gNamesAbbrTag, tempStatus), tempStatus); 1583 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calData.getByKey2(gMonthPatternsTag, gNamesNarrowTag, tempStatus), tempStatus); 1584 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus); 1585 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus); 1586 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus); 1587 initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calData.getByKey3(gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus); 1588 if (U_SUCCESS(tempStatus)) { 1589 // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't. 1590 // The ordering of the following statements is important. 1591 if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) { 1592 fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); 1593 }; 1594 if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) { 1595 fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]); 1596 }; 1597 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) { 1598 fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); 1599 }; 1600 if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) { 1601 fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]); 1602 }; 1603 // end of hack 1604 fLeapMonthPatternsCount = kMonthPatternsCount; 1605 } else { 1606 delete[] fLeapMonthPatterns; 1607 fLeapMonthPatterns = NULL; 1608 } 1609 } 1610 } 1611 1612 tempStatus = U_ZERO_ERROR; 1613 UResourceBundle *cyclicNameSets= calData.getByKey(gCyclicNameSetsTag, tempStatus); 1614 if (U_SUCCESS(tempStatus) && cyclicNameSets != NULL) { 1615 UResourceBundle *nameSetYears = ures_getByKeyWithFallback(cyclicNameSets, gNameSetYearsTag, NULL, &tempStatus); 1616 if (U_SUCCESS(tempStatus)) { 1617 UResourceBundle *nameSetYearsFmt = ures_getByKeyWithFallback(nameSetYears, gNamesFormatTag, NULL, &tempStatus); 1618 if (U_SUCCESS(tempStatus)) { 1619 UResourceBundle *nameSetYearsFmtAbbrev = ures_getByKeyWithFallback(nameSetYearsFmt, gNamesAbbrTag, NULL, &tempStatus); 1620 if (U_SUCCESS(tempStatus)) { 1621 initField(&fShortYearNames, fShortYearNamesCount, nameSetYearsFmtAbbrev, tempStatus); 1622 ures_close(nameSetYearsFmtAbbrev); 1623 } 1624 ures_close(nameSetYearsFmt); 1625 } 1626 ures_close(nameSetYears); 1627 } 1628 UResourceBundle *nameSetZodiacs = ures_getByKeyWithFallback(cyclicNameSets, gNameSetZodiacsTag, NULL, &tempStatus); 1629 if (U_SUCCESS(tempStatus)) { 1630 UResourceBundle *nameSetZodiacsFmt = ures_getByKeyWithFallback(nameSetZodiacs, gNamesFormatTag, NULL, &tempStatus); 1631 if (U_SUCCESS(tempStatus)) { 1632 UResourceBundle *nameSetZodiacsFmtAbbrev = ures_getByKeyWithFallback(nameSetZodiacsFmt, gNamesAbbrTag, NULL, &tempStatus); 1633 if (U_SUCCESS(tempStatus)) { 1634 initField(&fShortZodiacNames, fShortZodiacNamesCount, nameSetZodiacsFmtAbbrev, tempStatus); 1635 ures_close(nameSetZodiacsFmtAbbrev); 1636 } 1637 ures_close(nameSetZodiacsFmt); 1638 } 1639 ures_close(nameSetZodiacs); 1640 } 1641 } 1642 1643 tempStatus = U_ZERO_ERROR; 1644 UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus); 1645 if (U_SUCCESS(tempStatus)) { 1646 UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, gContextTransformsTag, NULL, &tempStatus); 1647 if (U_SUCCESS(tempStatus)) { 1648 UResourceBundle *contextTransformUsage; 1649 while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &tempStatus)) != NULL ) { 1650 const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status); 1651 if (U_SUCCESS(tempStatus) && intVector != NULL && len >= 2) { 1652 const char* usageType = ures_getKey(contextTransformUsage); 1653 if (usageType != NULL) { 1654 const ContextUsageTypeNameToEnumValue * typeMapPtr = contextUsageTypeMap; 1655 int32_t compResult = 0; 1656 // linear search; list is short and we cannot be sure that bsearch is available 1657 while ( typeMapPtr->usageTypeName != NULL && (compResult = uprv_strcmp(usageType, typeMapPtr->usageTypeName)) > 0 ) { 1658 ++typeMapPtr; 1659 } 1660 if (typeMapPtr->usageTypeName != NULL && compResult == 0) { 1661 fCapitalization[typeMapPtr->usageTypeEnumValue][0] = intVector[0]; 1662 fCapitalization[typeMapPtr->usageTypeEnumValue][1] = intVector[1]; 1663 } 1664 } 1665 } 1666 tempStatus = U_ZERO_ERROR; 1667 ures_close(contextTransformUsage); 1668 } 1669 ures_close(contextTransforms); 1670 } 1671 1672 tempStatus = U_ZERO_ERROR; 1673 const LocalPointer<NumberingSystem> numberingSystem( 1674 NumberingSystem::createInstance(locale, tempStatus), tempStatus); 1675 if (U_SUCCESS(tempStatus)) { 1676 // These functions all fail gracefully if passed NULL pointers and 1677 // do nothing unless U_SUCCESS(tempStatus), so it's only necessary 1678 // to check for errors once after all calls are made. 1679 const LocalUResourceBundlePointer numberElementsData(ures_getByKeyWithFallback( 1680 localeBundle, gNumberElementsTag, NULL, &tempStatus)); 1681 const LocalUResourceBundlePointer nsNameData(ures_getByKeyWithFallback( 1682 numberElementsData.getAlias(), numberingSystem->getName(), NULL, &tempStatus)); 1683 const LocalUResourceBundlePointer symbolsData(ures_getByKeyWithFallback( 1684 nsNameData.getAlias(), gSymbolsTag, NULL, &tempStatus)); 1685 fTimeSeparator = ures_getUnicodeStringByKey( 1686 symbolsData.getAlias(), gTimeSeparatorTag, &tempStatus); 1687 if (U_FAILURE(tempStatus)) { 1688 fTimeSeparator.setToBogus(); 1689 } 1690 } 1691 1692 ures_close(localeBundle); 1693 } 1694 1695 if (fTimeSeparator.isBogus()) { 1696 fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR); 1697 } 1698 1699 UResourceBundle *weekdaysData = NULL; // Data closed by calData 1700 UResourceBundle *abbrWeekdaysData = NULL; // Data closed by calData 1701 UResourceBundle *shorterWeekdaysData = NULL; // Data closed by calData 1702 UResourceBundle *narrowWeekdaysData = NULL; // Data closed by calData 1703 UResourceBundle *standaloneWeekdaysData = NULL; // Data closed by calData 1704 UResourceBundle *standaloneAbbrWeekdaysData = NULL; // Data closed by calData 1705 UResourceBundle *standaloneShorterWeekdaysData = NULL; // Data closed by calData 1706 UResourceBundle *standaloneNarrowWeekdaysData = NULL; // Data closed by calData 1707 1708 U_LOCALE_BASED(locBased, *this); 1709 if (U_FAILURE(status)) 1710 { 1711 if (useLastResortData) 1712 { 1713 // Handle the case in which there is no resource data present. 1714 // We don't have to generate usable patterns in this situation; 1715 // we just need to produce something that will be semi-intelligible 1716 // in most locales. 1717 1718 status = U_USING_FALLBACK_WARNING; 1719 1720 initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); 1721 initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); 1722 initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); 1723 initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1724 initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1725 initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1726 initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1727 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1728 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); 1729 initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1730 initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1731 initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1732 initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1733 initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1734 initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1735 initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1736 initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); 1737 initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); 1738 initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); 1739 initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); 1740 initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); 1741 initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); 1742 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); 1743 fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN); 1744 } 1745 goto cleanup; 1746 } 1747 1748 // if we make it to here, the resource data is cool, and we can get everything out 1749 // of it that we need except for the time-zone and localized-pattern data, which 1750 // are stored in a separate file 1751 locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status), 1752 ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status)); 1753 1754 initField(&fEras, fErasCount, eras, status); 1755 initField(&fEraNames, fEraNamesCount, eraNames, status); 1756 initField(&fNarrowEras, fNarrowErasCount, narrowEras, status); 1757 1758 initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status); 1759 initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); 1760 1761 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status); 1762 if(status == U_MISSING_RESOURCE_ERROR) { 1763 status = U_ZERO_ERROR; 1764 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status); 1765 } 1766 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If format/narrow not available, use format/abbreviated */ 1767 status = U_ZERO_ERROR; 1768 initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); 1769 } 1770 1771 initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status); 1772 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/wide not available, use format/wide */ 1773 status = U_ZERO_ERROR; 1774 initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status); 1775 } 1776 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); 1777 if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/abbreviated not available, use format/abbreviated */ 1778 status = U_ZERO_ERROR; 1779 initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); 1780 } 1781 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status); 1782 if ( status == U_MISSING_RESOURCE_ERROR ) { /* if standalone/narrow not availabe, try format/narrow */ 1783 status = U_ZERO_ERROR; 1784 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status); 1785 if ( status == U_MISSING_RESOURCE_ERROR ) { /* if still not there, use format/abbreviated */ 1786 status = U_ZERO_ERROR; 1787 initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); 1788 } 1789 } 1790 initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status); 1791 initField(&fNarrowAmPms, fNarrowAmPmsCount, calData.getByKey(gAmPmMarkersNarrowTag, status), status); 1792 1793 initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status); 1794 initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status); 1795 1796 initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status); 1797 if(status == U_MISSING_RESOURCE_ERROR) { 1798 status = U_ZERO_ERROR; 1799 initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status); 1800 } 1801 1802 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); 1803 if(status == U_MISSING_RESOURCE_ERROR) { 1804 status = U_ZERO_ERROR; 1805 initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status); 1806 } 1807 1808 // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597) 1809 /* 1810 // fastCopyFrom()/setTo() - see assignArray comments 1811 resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status); 1812 fLocalPatternChars.setTo(TRUE, resStr, len); 1813 // If the locale data does not include new pattern chars, use the defaults 1814 // TODO: Consider making this an error, since this may add conflicting characters. 1815 if (len < PATTERN_CHARS_LEN) { 1816 fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len)); 1817 } 1818 */ 1819 fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN); 1820 1821 // Format wide weekdays -> fWeekdays 1822 // {sfb} fixed to handle 1-based weekdays 1823 weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status); 1824 fWeekdaysCount = ures_getSize(weekdaysData); 1825 fWeekdays = new UnicodeString[fWeekdaysCount+1]; 1826 /* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/ 1827 if (fWeekdays == NULL) { 1828 status = U_MEMORY_ALLOCATION_ERROR; 1829 goto cleanup; 1830 } 1831 // leave fWeekdays[0] empty 1832 for(i = 0; i<fWeekdaysCount; i++) { 1833 resStr = ures_getStringByIndex(weekdaysData, i, &len, &status); 1834 // setTo() - see assignArray comments 1835 fWeekdays[i+1].setTo(TRUE, resStr, len); 1836 } 1837 fWeekdaysCount++; 1838 1839 // Format abbreviated weekdays -> fShortWeekdays 1840 abbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1841 fShortWeekdaysCount = ures_getSize(abbrWeekdaysData); 1842 fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1]; 1843 /* test for NULL */ 1844 if (fShortWeekdays == 0) { 1845 status = U_MEMORY_ALLOCATION_ERROR; 1846 goto cleanup; 1847 } 1848 // leave fShortWeekdays[0] empty 1849 for(i = 0; i<fShortWeekdaysCount; i++) { 1850 resStr = ures_getStringByIndex(abbrWeekdaysData, i, &len, &status); 1851 // setTo() - see assignArray comments 1852 fShortWeekdays[i+1].setTo(TRUE, resStr, len); 1853 } 1854 fShortWeekdaysCount++; 1855 1856 // Format short weekdays -> fShorterWeekdays (fall back to abbreviated) 1857 shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesShortTag, status); 1858 if ( status == U_MISSING_RESOURCE_ERROR ) { 1859 status = U_ZERO_ERROR; 1860 shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1861 } 1862 fShorterWeekdaysCount = ures_getSize(shorterWeekdaysData); 1863 fShorterWeekdays = new UnicodeString[fShorterWeekdaysCount+1]; 1864 /* test for NULL */ 1865 if (fShorterWeekdays == 0) { 1866 status = U_MEMORY_ALLOCATION_ERROR; 1867 goto cleanup; 1868 } 1869 // leave fShorterWeekdays[0] empty 1870 for(i = 0; i<fShorterWeekdaysCount; i++) { 1871 resStr = ures_getStringByIndex(shorterWeekdaysData, i, &len, &status); 1872 // setTo() - see assignArray comments 1873 fShorterWeekdays[i+1].setTo(TRUE, resStr, len); 1874 } 1875 fShorterWeekdaysCount++; 1876 1877 // Format narrow weekdays -> fNarrowWeekdays 1878 narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status); 1879 if(status == U_MISSING_RESOURCE_ERROR) { 1880 status = U_ZERO_ERROR; 1881 narrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status); 1882 } 1883 if ( status == U_MISSING_RESOURCE_ERROR ) { 1884 status = U_ZERO_ERROR; 1885 narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1886 } 1887 fNarrowWeekdaysCount = ures_getSize(narrowWeekdaysData); 1888 fNarrowWeekdays = new UnicodeString[fNarrowWeekdaysCount+1]; 1889 /* test for NULL */ 1890 if (fNarrowWeekdays == 0) { 1891 status = U_MEMORY_ALLOCATION_ERROR; 1892 goto cleanup; 1893 } 1894 // leave fNarrowWeekdays[0] empty 1895 for(i = 0; i<fNarrowWeekdaysCount; i++) { 1896 resStr = ures_getStringByIndex(narrowWeekdaysData, i, &len, &status); 1897 // setTo() - see assignArray comments 1898 fNarrowWeekdays[i+1].setTo(TRUE, resStr, len); 1899 } 1900 fNarrowWeekdaysCount++; 1901 1902 // Stand-alone wide weekdays -> fStandaloneWeekdays 1903 standaloneWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status); 1904 if ( status == U_MISSING_RESOURCE_ERROR ) { 1905 status = U_ZERO_ERROR; 1906 standaloneWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status); 1907 } 1908 fStandaloneWeekdaysCount = ures_getSize(standaloneWeekdaysData); 1909 fStandaloneWeekdays = new UnicodeString[fStandaloneWeekdaysCount+1]; 1910 /* test for NULL */ 1911 if (fStandaloneWeekdays == 0) { 1912 status = U_MEMORY_ALLOCATION_ERROR; 1913 goto cleanup; 1914 } 1915 // leave fStandaloneWeekdays[0] empty 1916 for(i = 0; i<fStandaloneWeekdaysCount; i++) { 1917 resStr = ures_getStringByIndex(standaloneWeekdaysData, i, &len, &status); 1918 // setTo() - see assignArray comments 1919 fStandaloneWeekdays[i+1].setTo(TRUE, resStr, len); 1920 } 1921 fStandaloneWeekdaysCount++; 1922 1923 // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays 1924 standaloneAbbrWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status); 1925 if ( status == U_MISSING_RESOURCE_ERROR ) { 1926 status = U_ZERO_ERROR; 1927 standaloneAbbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1928 } 1929 fStandaloneShortWeekdaysCount = ures_getSize(standaloneAbbrWeekdaysData); 1930 fStandaloneShortWeekdays = new UnicodeString[fStandaloneShortWeekdaysCount+1]; 1931 /* test for NULL */ 1932 if (fStandaloneShortWeekdays == 0) { 1933 status = U_MEMORY_ALLOCATION_ERROR; 1934 goto cleanup; 1935 } 1936 // leave fStandaloneShortWeekdays[0] empty 1937 for(i = 0; i<fStandaloneShortWeekdaysCount; i++) { 1938 resStr = ures_getStringByIndex(standaloneAbbrWeekdaysData, i, &len, &status); 1939 // setTo() - see assignArray comments 1940 fStandaloneShortWeekdays[i+1].setTo(TRUE, resStr, len); 1941 } 1942 fStandaloneShortWeekdaysCount++; 1943 1944 // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated) 1945 standaloneShorterWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status); 1946 if ( status == U_MISSING_RESOURCE_ERROR ) { 1947 status = U_ZERO_ERROR; 1948 standaloneShorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1949 } 1950 fStandaloneShorterWeekdaysCount = ures_getSize(standaloneShorterWeekdaysData); 1951 fStandaloneShorterWeekdays = new UnicodeString[fStandaloneShorterWeekdaysCount+1]; 1952 /* test for NULL */ 1953 if (fStandaloneShorterWeekdays == 0) { 1954 status = U_MEMORY_ALLOCATION_ERROR; 1955 goto cleanup; 1956 } 1957 // leave fStandaloneShorterWeekdays[0] empty 1958 for(i = 0; i<fStandaloneShorterWeekdaysCount; i++) { 1959 resStr = ures_getStringByIndex(standaloneShorterWeekdaysData, i, &len, &status); 1960 // setTo() - see assignArray comments 1961 fStandaloneShorterWeekdays[i+1].setTo(TRUE, resStr, len); 1962 } 1963 fStandaloneShorterWeekdaysCount++; 1964 1965 // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays 1966 standaloneNarrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status); 1967 if ( status == U_MISSING_RESOURCE_ERROR ) { 1968 status = U_ZERO_ERROR; 1969 standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status); 1970 if ( status == U_MISSING_RESOURCE_ERROR ) { 1971 status = U_ZERO_ERROR; 1972 standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); 1973 } 1974 } 1975 fStandaloneNarrowWeekdaysCount = ures_getSize(standaloneNarrowWeekdaysData); 1976 fStandaloneNarrowWeekdays = new UnicodeString[fStandaloneNarrowWeekdaysCount+1]; 1977 /* test for NULL */ 1978 if (fStandaloneNarrowWeekdays == 0) { 1979 status = U_MEMORY_ALLOCATION_ERROR; 1980 goto cleanup; 1981 } 1982 // leave fStandaloneNarrowWeekdays[0] empty 1983 for(i = 0; i<fStandaloneNarrowWeekdaysCount; i++) { 1984 resStr = ures_getStringByIndex(standaloneNarrowWeekdaysData, i, &len, &status); 1985 // setTo() - see assignArray comments 1986 fStandaloneNarrowWeekdays[i+1].setTo(TRUE, resStr, len); 1987 } 1988 fStandaloneNarrowWeekdaysCount++; 1989 1990 cleanup: 1991 ures_close(eras); 1992 ures_close(eraNames); 1993 ures_close(narrowEras); 1994 } 1995 1996 Locale 1997 DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const { 1998 U_LOCALE_BASED(locBased, *this); 1999 return locBased.getLocale(type, status); 2000 } 2001 2002 U_NAMESPACE_END 2003 2004 #endif /* #if !UCONFIG_NO_FORMATTING */ 2005 2006 //eof 2007