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