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