Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* |
michael@0 | 2 | ******************************************************************************* |
michael@0 | 3 | * Copyright (C) 1996-2013, International Business Machines |
michael@0 | 4 | * Corporation and others. All Rights Reserved. |
michael@0 | 5 | ******************************************************************************* |
michael@0 | 6 | */ |
michael@0 | 7 | |
michael@0 | 8 | #include "unicode/utypes.h" |
michael@0 | 9 | |
michael@0 | 10 | #if !UCONFIG_NO_FORMATTING |
michael@0 | 11 | |
michael@0 | 12 | #include "unicode/udat.h" |
michael@0 | 13 | |
michael@0 | 14 | #include "unicode/uloc.h" |
michael@0 | 15 | #include "unicode/datefmt.h" |
michael@0 | 16 | #include "unicode/timezone.h" |
michael@0 | 17 | #include "unicode/smpdtfmt.h" |
michael@0 | 18 | #include "unicode/fieldpos.h" |
michael@0 | 19 | #include "unicode/parsepos.h" |
michael@0 | 20 | #include "unicode/calendar.h" |
michael@0 | 21 | #include "unicode/numfmt.h" |
michael@0 | 22 | #include "unicode/dtfmtsym.h" |
michael@0 | 23 | #include "unicode/ustring.h" |
michael@0 | 24 | #include "unicode/udisplaycontext.h" |
michael@0 | 25 | #include "cpputils.h" |
michael@0 | 26 | #include "reldtfmt.h" |
michael@0 | 27 | #include "umutex.h" |
michael@0 | 28 | |
michael@0 | 29 | U_NAMESPACE_USE |
michael@0 | 30 | |
michael@0 | 31 | /** |
michael@0 | 32 | * Verify that fmt is a SimpleDateFormat. Invalid error if not. |
michael@0 | 33 | * @param fmt the UDateFormat, definitely a DateFormat, maybe something else |
michael@0 | 34 | * @param status error code, will be set to failure if there is a familure or the fmt is NULL. |
michael@0 | 35 | */ |
michael@0 | 36 | static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) { |
michael@0 | 37 | if(U_SUCCESS(*status) && |
michael@0 | 38 | dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { |
michael@0 | 39 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 40 | } |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | // This mirrors the correspondence between the |
michael@0 | 44 | // SimpleDateFormat::fgPatternIndexToDateFormatField and |
michael@0 | 45 | // SimpleDateFormat::fgPatternIndexToCalendarField arrays. |
michael@0 | 46 | static UCalendarDateFields gDateFieldMapping[] = { |
michael@0 | 47 | UCAL_ERA, // UDAT_ERA_FIELD = 0 |
michael@0 | 48 | UCAL_YEAR, // UDAT_YEAR_FIELD = 1 |
michael@0 | 49 | UCAL_MONTH, // UDAT_MONTH_FIELD = 2 |
michael@0 | 50 | UCAL_DATE, // UDAT_DATE_FIELD = 3 |
michael@0 | 51 | UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4 |
michael@0 | 52 | UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5 |
michael@0 | 53 | UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6 |
michael@0 | 54 | UCAL_SECOND, // UDAT_SECOND_FIELD = 7 |
michael@0 | 55 | UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8 |
michael@0 | 56 | UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9 |
michael@0 | 57 | UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10 |
michael@0 | 58 | UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11 |
michael@0 | 59 | UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12 |
michael@0 | 60 | UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13 |
michael@0 | 61 | UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14 |
michael@0 | 62 | UCAL_HOUR, // UDAT_HOUR1_FIELD = 15 |
michael@0 | 63 | UCAL_HOUR, // UDAT_HOUR0_FIELD = 16 |
michael@0 | 64 | UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17 |
michael@0 | 65 | UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18 |
michael@0 | 66 | UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19 |
michael@0 | 67 | UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20 |
michael@0 | 68 | UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21 |
michael@0 | 69 | UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22 |
michael@0 | 70 | UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 |
michael@0 | 71 | // UCAL_DST_OFFSET also |
michael@0 | 72 | UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 |
michael@0 | 73 | UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25 |
michael@0 | 74 | UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26 |
michael@0 | 75 | UCAL_MONTH, // UDAT_QUARTER_FIELD = 27 |
michael@0 | 76 | UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28 |
michael@0 | 77 | UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 |
michael@0 | 78 | UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30 |
michael@0 | 79 | UCAL_FIELD_COUNT, // UDAT_FIELD_COUNT = 31 |
michael@0 | 80 | // UCAL_IS_LEAP_MONTH is not the target of a mapping |
michael@0 | 81 | }; |
michael@0 | 82 | |
michael@0 | 83 | U_CAPI UCalendarDateFields U_EXPORT2 |
michael@0 | 84 | udat_toCalendarDateField(UDateFormatField field) { |
michael@0 | 85 | return gDateFieldMapping[field]; |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | /* For now- one opener. */ |
michael@0 | 89 | static UDateFormatOpener gOpener = NULL; |
michael@0 | 90 | |
michael@0 | 91 | U_INTERNAL void U_EXPORT2 |
michael@0 | 92 | udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) |
michael@0 | 93 | { |
michael@0 | 94 | if(U_FAILURE(*status)) return; |
michael@0 | 95 | umtx_lock(NULL); |
michael@0 | 96 | if(gOpener==NULL) { |
michael@0 | 97 | gOpener = opener; |
michael@0 | 98 | } else { |
michael@0 | 99 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 100 | } |
michael@0 | 101 | umtx_unlock(NULL); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | U_INTERNAL UDateFormatOpener U_EXPORT2 |
michael@0 | 105 | udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status) |
michael@0 | 106 | { |
michael@0 | 107 | if(U_FAILURE(*status)) return NULL; |
michael@0 | 108 | UDateFormatOpener oldOpener = NULL; |
michael@0 | 109 | umtx_lock(NULL); |
michael@0 | 110 | if(gOpener==NULL || gOpener!=opener) { |
michael@0 | 111 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 112 | } else { |
michael@0 | 113 | oldOpener=gOpener; |
michael@0 | 114 | gOpener=NULL; |
michael@0 | 115 | } |
michael@0 | 116 | umtx_unlock(NULL); |
michael@0 | 117 | return oldOpener; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | |
michael@0 | 121 | |
michael@0 | 122 | U_CAPI UDateFormat* U_EXPORT2 |
michael@0 | 123 | udat_open(UDateFormatStyle timeStyle, |
michael@0 | 124 | UDateFormatStyle dateStyle, |
michael@0 | 125 | const char *locale, |
michael@0 | 126 | const UChar *tzID, |
michael@0 | 127 | int32_t tzIDLength, |
michael@0 | 128 | const UChar *pattern, |
michael@0 | 129 | int32_t patternLength, |
michael@0 | 130 | UErrorCode *status) |
michael@0 | 131 | { |
michael@0 | 132 | DateFormat *fmt; |
michael@0 | 133 | if(U_FAILURE(*status)) { |
michael@0 | 134 | return 0; |
michael@0 | 135 | } |
michael@0 | 136 | if(gOpener!=NULL) { // if it's registered |
michael@0 | 137 | fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status); |
michael@0 | 138 | if(fmt!=NULL) { |
michael@0 | 139 | return (UDateFormat*)fmt; |
michael@0 | 140 | } // else fall through. |
michael@0 | 141 | } |
michael@0 | 142 | if(timeStyle != UDAT_PATTERN) { |
michael@0 | 143 | if(locale == 0) { |
michael@0 | 144 | fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, |
michael@0 | 145 | (DateFormat::EStyle)timeStyle); |
michael@0 | 146 | } |
michael@0 | 147 | else { |
michael@0 | 148 | fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, |
michael@0 | 149 | (DateFormat::EStyle)timeStyle, |
michael@0 | 150 | Locale(locale)); |
michael@0 | 151 | } |
michael@0 | 152 | } |
michael@0 | 153 | else { |
michael@0 | 154 | UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); |
michael@0 | 155 | |
michael@0 | 156 | if(locale == 0) { |
michael@0 | 157 | fmt = new SimpleDateFormat(pat, *status); |
michael@0 | 158 | } |
michael@0 | 159 | else { |
michael@0 | 160 | fmt = new SimpleDateFormat(pat, Locale(locale), *status); |
michael@0 | 161 | } |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | if(fmt == 0) { |
michael@0 | 165 | *status = U_MEMORY_ALLOCATION_ERROR; |
michael@0 | 166 | return 0; |
michael@0 | 167 | } |
michael@0 | 168 | |
michael@0 | 169 | if(tzID != 0) { |
michael@0 | 170 | TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength)); |
michael@0 | 171 | if(zone == 0) { |
michael@0 | 172 | *status = U_MEMORY_ALLOCATION_ERROR; |
michael@0 | 173 | delete fmt; |
michael@0 | 174 | return 0; |
michael@0 | 175 | } |
michael@0 | 176 | fmt->adoptTimeZone(zone); |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | return (UDateFormat*)fmt; |
michael@0 | 180 | } |
michael@0 | 181 | |
michael@0 | 182 | |
michael@0 | 183 | U_CAPI void U_EXPORT2 |
michael@0 | 184 | udat_close(UDateFormat* format) |
michael@0 | 185 | { |
michael@0 | 186 | delete (DateFormat*)format; |
michael@0 | 187 | } |
michael@0 | 188 | |
michael@0 | 189 | U_CAPI UDateFormat* U_EXPORT2 |
michael@0 | 190 | udat_clone(const UDateFormat *fmt, |
michael@0 | 191 | UErrorCode *status) |
michael@0 | 192 | { |
michael@0 | 193 | if(U_FAILURE(*status)) return 0; |
michael@0 | 194 | |
michael@0 | 195 | Format *res = ((DateFormat*)fmt)->clone(); |
michael@0 | 196 | |
michael@0 | 197 | if(res == 0) { |
michael@0 | 198 | *status = U_MEMORY_ALLOCATION_ERROR; |
michael@0 | 199 | return 0; |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | return (UDateFormat*) res; |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 206 | udat_format( const UDateFormat* format, |
michael@0 | 207 | UDate dateToFormat, |
michael@0 | 208 | UChar* result, |
michael@0 | 209 | int32_t resultLength, |
michael@0 | 210 | UFieldPosition* position, |
michael@0 | 211 | UErrorCode* status) |
michael@0 | 212 | { |
michael@0 | 213 | if(U_FAILURE(*status)) return -1; |
michael@0 | 214 | |
michael@0 | 215 | UnicodeString res; |
michael@0 | 216 | if(!(result==NULL && resultLength==0)) { |
michael@0 | 217 | // NULL destination for pure preflighting: empty dummy string |
michael@0 | 218 | // otherwise, alias the destination buffer |
michael@0 | 219 | res.setTo(result, 0, resultLength); |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | FieldPosition fp; |
michael@0 | 223 | |
michael@0 | 224 | if(position != 0) |
michael@0 | 225 | fp.setField(position->field); |
michael@0 | 226 | |
michael@0 | 227 | ((DateFormat*)format)->format(dateToFormat, res, fp); |
michael@0 | 228 | |
michael@0 | 229 | if(position != 0) { |
michael@0 | 230 | position->beginIndex = fp.getBeginIndex(); |
michael@0 | 231 | position->endIndex = fp.getEndIndex(); |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | return res.extract(result, resultLength, *status); |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | U_CAPI UDate U_EXPORT2 |
michael@0 | 238 | udat_parse( const UDateFormat* format, |
michael@0 | 239 | const UChar* text, |
michael@0 | 240 | int32_t textLength, |
michael@0 | 241 | int32_t *parsePos, |
michael@0 | 242 | UErrorCode *status) |
michael@0 | 243 | { |
michael@0 | 244 | if(U_FAILURE(*status)) return (UDate)0; |
michael@0 | 245 | |
michael@0 | 246 | const UnicodeString src((UBool)(textLength == -1), text, textLength); |
michael@0 | 247 | ParsePosition pp; |
michael@0 | 248 | int32_t stackParsePos = 0; |
michael@0 | 249 | UDate res; |
michael@0 | 250 | |
michael@0 | 251 | if(parsePos == NULL) { |
michael@0 | 252 | parsePos = &stackParsePos; |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | pp.setIndex(*parsePos); |
michael@0 | 256 | |
michael@0 | 257 | res = ((DateFormat*)format)->parse(src, pp); |
michael@0 | 258 | |
michael@0 | 259 | if(pp.getErrorIndex() == -1) |
michael@0 | 260 | *parsePos = pp.getIndex(); |
michael@0 | 261 | else { |
michael@0 | 262 | *parsePos = pp.getErrorIndex(); |
michael@0 | 263 | *status = U_PARSE_ERROR; |
michael@0 | 264 | } |
michael@0 | 265 | |
michael@0 | 266 | return res; |
michael@0 | 267 | } |
michael@0 | 268 | |
michael@0 | 269 | U_CAPI void U_EXPORT2 |
michael@0 | 270 | udat_parseCalendar(const UDateFormat* format, |
michael@0 | 271 | UCalendar* calendar, |
michael@0 | 272 | const UChar* text, |
michael@0 | 273 | int32_t textLength, |
michael@0 | 274 | int32_t *parsePos, |
michael@0 | 275 | UErrorCode *status) |
michael@0 | 276 | { |
michael@0 | 277 | if(U_FAILURE(*status)) return; |
michael@0 | 278 | |
michael@0 | 279 | const UnicodeString src((UBool)(textLength == -1), text, textLength); |
michael@0 | 280 | ParsePosition pp; |
michael@0 | 281 | |
michael@0 | 282 | if(parsePos != 0) |
michael@0 | 283 | pp.setIndex(*parsePos); |
michael@0 | 284 | |
michael@0 | 285 | ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp); |
michael@0 | 286 | |
michael@0 | 287 | if(parsePos != 0) { |
michael@0 | 288 | if(pp.getErrorIndex() == -1) |
michael@0 | 289 | *parsePos = pp.getIndex(); |
michael@0 | 290 | else { |
michael@0 | 291 | *parsePos = pp.getErrorIndex(); |
michael@0 | 292 | *status = U_PARSE_ERROR; |
michael@0 | 293 | } |
michael@0 | 294 | } |
michael@0 | 295 | } |
michael@0 | 296 | |
michael@0 | 297 | U_CAPI UBool U_EXPORT2 |
michael@0 | 298 | udat_isLenient(const UDateFormat* fmt) |
michael@0 | 299 | { |
michael@0 | 300 | return ((DateFormat*)fmt)->isLenient(); |
michael@0 | 301 | } |
michael@0 | 302 | |
michael@0 | 303 | U_CAPI void U_EXPORT2 |
michael@0 | 304 | udat_setLenient( UDateFormat* fmt, |
michael@0 | 305 | UBool isLenient) |
michael@0 | 306 | { |
michael@0 | 307 | ((DateFormat*)fmt)->setLenient(isLenient); |
michael@0 | 308 | } |
michael@0 | 309 | |
michael@0 | 310 | U_CAPI const UCalendar* U_EXPORT2 |
michael@0 | 311 | udat_getCalendar(const UDateFormat* fmt) |
michael@0 | 312 | { |
michael@0 | 313 | return (const UCalendar*) ((DateFormat*)fmt)->getCalendar(); |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | U_CAPI void U_EXPORT2 |
michael@0 | 317 | udat_setCalendar(UDateFormat* fmt, |
michael@0 | 318 | const UCalendar* calendarToSet) |
michael@0 | 319 | { |
michael@0 | 320 | ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet)); |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | U_CAPI const UNumberFormat* U_EXPORT2 |
michael@0 | 324 | udat_getNumberFormat(const UDateFormat* fmt) |
michael@0 | 325 | { |
michael@0 | 326 | return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | U_CAPI void U_EXPORT2 |
michael@0 | 330 | udat_setNumberFormat(UDateFormat* fmt, |
michael@0 | 331 | const UNumberFormat* numberFormatToSet) |
michael@0 | 332 | { |
michael@0 | 333 | ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet)); |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | U_CAPI const char* U_EXPORT2 |
michael@0 | 337 | udat_getAvailable(int32_t index) |
michael@0 | 338 | { |
michael@0 | 339 | return uloc_getAvailable(index); |
michael@0 | 340 | } |
michael@0 | 341 | |
michael@0 | 342 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 343 | udat_countAvailable() |
michael@0 | 344 | { |
michael@0 | 345 | return uloc_countAvailable(); |
michael@0 | 346 | } |
michael@0 | 347 | |
michael@0 | 348 | U_CAPI UDate U_EXPORT2 |
michael@0 | 349 | udat_get2DigitYearStart( const UDateFormat *fmt, |
michael@0 | 350 | UErrorCode *status) |
michael@0 | 351 | { |
michael@0 | 352 | verifyIsSimpleDateFormat(fmt, status); |
michael@0 | 353 | if(U_FAILURE(*status)) return (UDate)0; |
michael@0 | 354 | return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status); |
michael@0 | 355 | } |
michael@0 | 356 | |
michael@0 | 357 | U_CAPI void U_EXPORT2 |
michael@0 | 358 | udat_set2DigitYearStart( UDateFormat *fmt, |
michael@0 | 359 | UDate d, |
michael@0 | 360 | UErrorCode *status) |
michael@0 | 361 | { |
michael@0 | 362 | verifyIsSimpleDateFormat(fmt, status); |
michael@0 | 363 | if(U_FAILURE(*status)) return; |
michael@0 | 364 | ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status); |
michael@0 | 365 | } |
michael@0 | 366 | |
michael@0 | 367 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 368 | udat_toPattern( const UDateFormat *fmt, |
michael@0 | 369 | UBool localized, |
michael@0 | 370 | UChar *result, |
michael@0 | 371 | int32_t resultLength, |
michael@0 | 372 | UErrorCode *status) |
michael@0 | 373 | { |
michael@0 | 374 | if(U_FAILURE(*status)) return -1; |
michael@0 | 375 | |
michael@0 | 376 | UnicodeString res; |
michael@0 | 377 | if(!(result==NULL && resultLength==0)) { |
michael@0 | 378 | // NULL destination for pure preflighting: empty dummy string |
michael@0 | 379 | // otherwise, alias the destination buffer |
michael@0 | 380 | res.setTo(result, 0, resultLength); |
michael@0 | 381 | } |
michael@0 | 382 | |
michael@0 | 383 | const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); |
michael@0 | 384 | const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); |
michael@0 | 385 | const RelativeDateFormat *reldtfmt; |
michael@0 | 386 | if (sdtfmt!=NULL) { |
michael@0 | 387 | if(localized) |
michael@0 | 388 | sdtfmt->toLocalizedPattern(res, *status); |
michael@0 | 389 | else |
michael@0 | 390 | sdtfmt->toPattern(res); |
michael@0 | 391 | } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) { |
michael@0 | 392 | reldtfmt->toPattern(res, *status); |
michael@0 | 393 | } else { |
michael@0 | 394 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 395 | return -1; |
michael@0 | 396 | } |
michael@0 | 397 | |
michael@0 | 398 | return res.extract(result, resultLength, *status); |
michael@0 | 399 | } |
michael@0 | 400 | |
michael@0 | 401 | // TODO: should this take an UErrorCode? |
michael@0 | 402 | // A: Yes. Of course. |
michael@0 | 403 | U_CAPI void U_EXPORT2 |
michael@0 | 404 | udat_applyPattern( UDateFormat *format, |
michael@0 | 405 | UBool localized, |
michael@0 | 406 | const UChar *pattern, |
michael@0 | 407 | int32_t patternLength) |
michael@0 | 408 | { |
michael@0 | 409 | const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); |
michael@0 | 410 | UErrorCode status = U_ZERO_ERROR; |
michael@0 | 411 | |
michael@0 | 412 | verifyIsSimpleDateFormat(format, &status); |
michael@0 | 413 | if(U_FAILURE(status)) { |
michael@0 | 414 | return; |
michael@0 | 415 | } |
michael@0 | 416 | |
michael@0 | 417 | if(localized) |
michael@0 | 418 | ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status); |
michael@0 | 419 | else |
michael@0 | 420 | ((SimpleDateFormat*)format)->applyPattern(pat); |
michael@0 | 421 | } |
michael@0 | 422 | |
michael@0 | 423 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 424 | udat_getSymbols(const UDateFormat *fmt, |
michael@0 | 425 | UDateFormatSymbolType type, |
michael@0 | 426 | int32_t index, |
michael@0 | 427 | UChar *result, |
michael@0 | 428 | int32_t resultLength, |
michael@0 | 429 | UErrorCode *status) |
michael@0 | 430 | { |
michael@0 | 431 | const DateFormatSymbols *syms; |
michael@0 | 432 | const SimpleDateFormat* sdtfmt; |
michael@0 | 433 | const RelativeDateFormat* rdtfmt; |
michael@0 | 434 | if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { |
michael@0 | 435 | syms = sdtfmt->getDateFormatSymbols(); |
michael@0 | 436 | } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { |
michael@0 | 437 | syms = rdtfmt->getDateFormatSymbols(); |
michael@0 | 438 | } else { |
michael@0 | 439 | return -1; |
michael@0 | 440 | } |
michael@0 | 441 | int32_t count; |
michael@0 | 442 | const UnicodeString *res = NULL; |
michael@0 | 443 | |
michael@0 | 444 | switch(type) { |
michael@0 | 445 | case UDAT_ERAS: |
michael@0 | 446 | res = syms->getEras(count); |
michael@0 | 447 | break; |
michael@0 | 448 | |
michael@0 | 449 | case UDAT_ERA_NAMES: |
michael@0 | 450 | res = syms->getEraNames(count); |
michael@0 | 451 | break; |
michael@0 | 452 | |
michael@0 | 453 | case UDAT_MONTHS: |
michael@0 | 454 | res = syms->getMonths(count); |
michael@0 | 455 | break; |
michael@0 | 456 | |
michael@0 | 457 | case UDAT_SHORT_MONTHS: |
michael@0 | 458 | res = syms->getShortMonths(count); |
michael@0 | 459 | break; |
michael@0 | 460 | |
michael@0 | 461 | case UDAT_WEEKDAYS: |
michael@0 | 462 | res = syms->getWeekdays(count); |
michael@0 | 463 | break; |
michael@0 | 464 | |
michael@0 | 465 | case UDAT_SHORT_WEEKDAYS: |
michael@0 | 466 | res = syms->getShortWeekdays(count); |
michael@0 | 467 | break; |
michael@0 | 468 | |
michael@0 | 469 | case UDAT_AM_PMS: |
michael@0 | 470 | res = syms->getAmPmStrings(count); |
michael@0 | 471 | break; |
michael@0 | 472 | |
michael@0 | 473 | case UDAT_LOCALIZED_CHARS: |
michael@0 | 474 | { |
michael@0 | 475 | UnicodeString res1; |
michael@0 | 476 | if(!(result==NULL && resultLength==0)) { |
michael@0 | 477 | // NULL destination for pure preflighting: empty dummy string |
michael@0 | 478 | // otherwise, alias the destination buffer |
michael@0 | 479 | res1.setTo(result, 0, resultLength); |
michael@0 | 480 | } |
michael@0 | 481 | syms->getLocalPatternChars(res1); |
michael@0 | 482 | return res1.extract(result, resultLength, *status); |
michael@0 | 483 | } |
michael@0 | 484 | |
michael@0 | 485 | case UDAT_NARROW_MONTHS: |
michael@0 | 486 | res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); |
michael@0 | 487 | break; |
michael@0 | 488 | |
michael@0 | 489 | case UDAT_SHORTER_WEEKDAYS: |
michael@0 | 490 | res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); |
michael@0 | 491 | break; |
michael@0 | 492 | |
michael@0 | 493 | case UDAT_NARROW_WEEKDAYS: |
michael@0 | 494 | res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); |
michael@0 | 495 | break; |
michael@0 | 496 | |
michael@0 | 497 | case UDAT_STANDALONE_MONTHS: |
michael@0 | 498 | res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 499 | break; |
michael@0 | 500 | |
michael@0 | 501 | case UDAT_STANDALONE_SHORT_MONTHS: |
michael@0 | 502 | res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 503 | break; |
michael@0 | 504 | |
michael@0 | 505 | case UDAT_STANDALONE_NARROW_MONTHS: |
michael@0 | 506 | res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); |
michael@0 | 507 | break; |
michael@0 | 508 | |
michael@0 | 509 | case UDAT_STANDALONE_WEEKDAYS: |
michael@0 | 510 | res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 511 | break; |
michael@0 | 512 | |
michael@0 | 513 | case UDAT_STANDALONE_SHORT_WEEKDAYS: |
michael@0 | 514 | res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 515 | break; |
michael@0 | 516 | |
michael@0 | 517 | case UDAT_STANDALONE_SHORTER_WEEKDAYS: |
michael@0 | 518 | res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); |
michael@0 | 519 | break; |
michael@0 | 520 | |
michael@0 | 521 | case UDAT_STANDALONE_NARROW_WEEKDAYS: |
michael@0 | 522 | res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); |
michael@0 | 523 | break; |
michael@0 | 524 | |
michael@0 | 525 | case UDAT_QUARTERS: |
michael@0 | 526 | res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); |
michael@0 | 527 | break; |
michael@0 | 528 | |
michael@0 | 529 | case UDAT_SHORT_QUARTERS: |
michael@0 | 530 | res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); |
michael@0 | 531 | break; |
michael@0 | 532 | |
michael@0 | 533 | case UDAT_STANDALONE_QUARTERS: |
michael@0 | 534 | res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 535 | break; |
michael@0 | 536 | |
michael@0 | 537 | case UDAT_STANDALONE_SHORT_QUARTERS: |
michael@0 | 538 | res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 539 | break; |
michael@0 | 540 | |
michael@0 | 541 | } |
michael@0 | 542 | |
michael@0 | 543 | if(index < count) { |
michael@0 | 544 | return res[index].extract(result, resultLength, *status); |
michael@0 | 545 | } |
michael@0 | 546 | return 0; |
michael@0 | 547 | } |
michael@0 | 548 | |
michael@0 | 549 | // TODO: also needs an errorCode. |
michael@0 | 550 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 551 | udat_countSymbols( const UDateFormat *fmt, |
michael@0 | 552 | UDateFormatSymbolType type) |
michael@0 | 553 | { |
michael@0 | 554 | const DateFormatSymbols *syms; |
michael@0 | 555 | const SimpleDateFormat* sdtfmt; |
michael@0 | 556 | const RelativeDateFormat* rdtfmt; |
michael@0 | 557 | if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { |
michael@0 | 558 | syms = sdtfmt->getDateFormatSymbols(); |
michael@0 | 559 | } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { |
michael@0 | 560 | syms = rdtfmt->getDateFormatSymbols(); |
michael@0 | 561 | } else { |
michael@0 | 562 | return 0; |
michael@0 | 563 | } |
michael@0 | 564 | int32_t count = 0; |
michael@0 | 565 | |
michael@0 | 566 | switch(type) { |
michael@0 | 567 | case UDAT_ERAS: |
michael@0 | 568 | syms->getEras(count); |
michael@0 | 569 | break; |
michael@0 | 570 | |
michael@0 | 571 | case UDAT_MONTHS: |
michael@0 | 572 | syms->getMonths(count); |
michael@0 | 573 | break; |
michael@0 | 574 | |
michael@0 | 575 | case UDAT_SHORT_MONTHS: |
michael@0 | 576 | syms->getShortMonths(count); |
michael@0 | 577 | break; |
michael@0 | 578 | |
michael@0 | 579 | case UDAT_WEEKDAYS: |
michael@0 | 580 | syms->getWeekdays(count); |
michael@0 | 581 | break; |
michael@0 | 582 | |
michael@0 | 583 | case UDAT_SHORT_WEEKDAYS: |
michael@0 | 584 | syms->getShortWeekdays(count); |
michael@0 | 585 | break; |
michael@0 | 586 | |
michael@0 | 587 | case UDAT_AM_PMS: |
michael@0 | 588 | syms->getAmPmStrings(count); |
michael@0 | 589 | break; |
michael@0 | 590 | |
michael@0 | 591 | case UDAT_LOCALIZED_CHARS: |
michael@0 | 592 | count = 1; |
michael@0 | 593 | break; |
michael@0 | 594 | |
michael@0 | 595 | case UDAT_ERA_NAMES: |
michael@0 | 596 | syms->getEraNames(count); |
michael@0 | 597 | break; |
michael@0 | 598 | |
michael@0 | 599 | case UDAT_NARROW_MONTHS: |
michael@0 | 600 | syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); |
michael@0 | 601 | break; |
michael@0 | 602 | |
michael@0 | 603 | case UDAT_SHORTER_WEEKDAYS: |
michael@0 | 604 | syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); |
michael@0 | 605 | break; |
michael@0 | 606 | |
michael@0 | 607 | case UDAT_NARROW_WEEKDAYS: |
michael@0 | 608 | syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); |
michael@0 | 609 | break; |
michael@0 | 610 | |
michael@0 | 611 | case UDAT_STANDALONE_MONTHS: |
michael@0 | 612 | syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 613 | break; |
michael@0 | 614 | |
michael@0 | 615 | case UDAT_STANDALONE_SHORT_MONTHS: |
michael@0 | 616 | syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 617 | break; |
michael@0 | 618 | |
michael@0 | 619 | case UDAT_STANDALONE_NARROW_MONTHS: |
michael@0 | 620 | syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); |
michael@0 | 621 | break; |
michael@0 | 622 | |
michael@0 | 623 | case UDAT_STANDALONE_WEEKDAYS: |
michael@0 | 624 | syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 625 | break; |
michael@0 | 626 | |
michael@0 | 627 | case UDAT_STANDALONE_SHORT_WEEKDAYS: |
michael@0 | 628 | syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 629 | break; |
michael@0 | 630 | |
michael@0 | 631 | case UDAT_STANDALONE_SHORTER_WEEKDAYS: |
michael@0 | 632 | syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); |
michael@0 | 633 | break; |
michael@0 | 634 | |
michael@0 | 635 | case UDAT_STANDALONE_NARROW_WEEKDAYS: |
michael@0 | 636 | syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); |
michael@0 | 637 | break; |
michael@0 | 638 | |
michael@0 | 639 | case UDAT_QUARTERS: |
michael@0 | 640 | syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); |
michael@0 | 641 | break; |
michael@0 | 642 | |
michael@0 | 643 | case UDAT_SHORT_QUARTERS: |
michael@0 | 644 | syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); |
michael@0 | 645 | break; |
michael@0 | 646 | |
michael@0 | 647 | case UDAT_STANDALONE_QUARTERS: |
michael@0 | 648 | syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); |
michael@0 | 649 | break; |
michael@0 | 650 | |
michael@0 | 651 | case UDAT_STANDALONE_SHORT_QUARTERS: |
michael@0 | 652 | syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); |
michael@0 | 653 | break; |
michael@0 | 654 | |
michael@0 | 655 | } |
michael@0 | 656 | |
michael@0 | 657 | return count; |
michael@0 | 658 | } |
michael@0 | 659 | |
michael@0 | 660 | U_NAMESPACE_BEGIN |
michael@0 | 661 | |
michael@0 | 662 | /* |
michael@0 | 663 | * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols |
michael@0 | 664 | * solely for the purpose of avoiding to clone the array of strings |
michael@0 | 665 | * just to modify one of them and then setting all of them back. |
michael@0 | 666 | * For example, the old code looked like this: |
michael@0 | 667 | * case UDAT_MONTHS: |
michael@0 | 668 | * res = syms->getMonths(count); |
michael@0 | 669 | * array = new UnicodeString[count]; |
michael@0 | 670 | * if(array == 0) { |
michael@0 | 671 | * *status = U_MEMORY_ALLOCATION_ERROR; |
michael@0 | 672 | * return; |
michael@0 | 673 | * } |
michael@0 | 674 | * uprv_arrayCopy(res, array, count); |
michael@0 | 675 | * if(index < count) |
michael@0 | 676 | * array[index] = val; |
michael@0 | 677 | * syms->setMonths(array, count); |
michael@0 | 678 | * break; |
michael@0 | 679 | * |
michael@0 | 680 | * Even worse, the old code actually cloned the entire DateFormatSymbols object, |
michael@0 | 681 | * cloned one value array, changed one value, and then made the SimpleDateFormat |
michael@0 | 682 | * replace its DateFormatSymbols object with the new one. |
michael@0 | 683 | * |
michael@0 | 684 | * markus 2002-oct-14 |
michael@0 | 685 | */ |
michael@0 | 686 | class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ { |
michael@0 | 687 | public: |
michael@0 | 688 | static void |
michael@0 | 689 | setSymbol(UnicodeString *array, int32_t count, int32_t index, |
michael@0 | 690 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 691 | { |
michael@0 | 692 | if(array!=NULL) { |
michael@0 | 693 | if(index>=count) { |
michael@0 | 694 | errorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
michael@0 | 695 | } else if(value==NULL) { |
michael@0 | 696 | errorCode=U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 697 | } else { |
michael@0 | 698 | array[index].setTo(value, valueLength); |
michael@0 | 699 | } |
michael@0 | 700 | } |
michael@0 | 701 | } |
michael@0 | 702 | |
michael@0 | 703 | static void |
michael@0 | 704 | setEra(DateFormatSymbols *syms, int32_t index, |
michael@0 | 705 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 706 | { |
michael@0 | 707 | setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode); |
michael@0 | 708 | } |
michael@0 | 709 | |
michael@0 | 710 | static void |
michael@0 | 711 | setEraName(DateFormatSymbols *syms, int32_t index, |
michael@0 | 712 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 713 | { |
michael@0 | 714 | setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode); |
michael@0 | 715 | } |
michael@0 | 716 | |
michael@0 | 717 | static void |
michael@0 | 718 | setMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 719 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 720 | { |
michael@0 | 721 | setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 722 | } |
michael@0 | 723 | |
michael@0 | 724 | static void |
michael@0 | 725 | setShortMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 726 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 727 | { |
michael@0 | 728 | setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 729 | } |
michael@0 | 730 | |
michael@0 | 731 | static void |
michael@0 | 732 | setNarrowMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 733 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 734 | { |
michael@0 | 735 | setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 736 | } |
michael@0 | 737 | |
michael@0 | 738 | static void |
michael@0 | 739 | setStandaloneMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 740 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 741 | { |
michael@0 | 742 | setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 743 | } |
michael@0 | 744 | |
michael@0 | 745 | static void |
michael@0 | 746 | setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 747 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 748 | { |
michael@0 | 749 | setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 750 | } |
michael@0 | 751 | |
michael@0 | 752 | static void |
michael@0 | 753 | setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, |
michael@0 | 754 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 755 | { |
michael@0 | 756 | setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode); |
michael@0 | 757 | } |
michael@0 | 758 | |
michael@0 | 759 | static void |
michael@0 | 760 | setWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 761 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 762 | { |
michael@0 | 763 | setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 764 | } |
michael@0 | 765 | |
michael@0 | 766 | static void |
michael@0 | 767 | setShortWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 768 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 769 | { |
michael@0 | 770 | setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 771 | } |
michael@0 | 772 | |
michael@0 | 773 | static void |
michael@0 | 774 | setShorterWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 775 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 776 | { |
michael@0 | 777 | setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 778 | } |
michael@0 | 779 | |
michael@0 | 780 | static void |
michael@0 | 781 | setNarrowWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 782 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 783 | { |
michael@0 | 784 | setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 785 | } |
michael@0 | 786 | |
michael@0 | 787 | static void |
michael@0 | 788 | setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 789 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 790 | { |
michael@0 | 791 | setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 792 | } |
michael@0 | 793 | |
michael@0 | 794 | static void |
michael@0 | 795 | setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 796 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 797 | { |
michael@0 | 798 | setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 799 | } |
michael@0 | 800 | |
michael@0 | 801 | static void |
michael@0 | 802 | setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 803 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 804 | { |
michael@0 | 805 | setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 806 | } |
michael@0 | 807 | |
michael@0 | 808 | static void |
michael@0 | 809 | setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, |
michael@0 | 810 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 811 | { |
michael@0 | 812 | setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode); |
michael@0 | 813 | } |
michael@0 | 814 | |
michael@0 | 815 | static void |
michael@0 | 816 | setQuarter(DateFormatSymbols *syms, int32_t index, |
michael@0 | 817 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 818 | { |
michael@0 | 819 | setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode); |
michael@0 | 820 | } |
michael@0 | 821 | |
michael@0 | 822 | static void |
michael@0 | 823 | setShortQuarter(DateFormatSymbols *syms, int32_t index, |
michael@0 | 824 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 825 | { |
michael@0 | 826 | setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode); |
michael@0 | 827 | } |
michael@0 | 828 | |
michael@0 | 829 | static void |
michael@0 | 830 | setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, |
michael@0 | 831 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 832 | { |
michael@0 | 833 | setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode); |
michael@0 | 834 | } |
michael@0 | 835 | |
michael@0 | 836 | static void |
michael@0 | 837 | setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, |
michael@0 | 838 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 839 | { |
michael@0 | 840 | setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode); |
michael@0 | 841 | } |
michael@0 | 842 | |
michael@0 | 843 | static void |
michael@0 | 844 | setAmPm(DateFormatSymbols *syms, int32_t index, |
michael@0 | 845 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 846 | { |
michael@0 | 847 | setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode); |
michael@0 | 848 | } |
michael@0 | 849 | |
michael@0 | 850 | static void |
michael@0 | 851 | setLocalPatternChars(DateFormatSymbols *syms, |
michael@0 | 852 | const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
michael@0 | 853 | { |
michael@0 | 854 | setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode); |
michael@0 | 855 | } |
michael@0 | 856 | }; |
michael@0 | 857 | |
michael@0 | 858 | U_NAMESPACE_END |
michael@0 | 859 | |
michael@0 | 860 | U_CAPI void U_EXPORT2 |
michael@0 | 861 | udat_setSymbols( UDateFormat *format, |
michael@0 | 862 | UDateFormatSymbolType type, |
michael@0 | 863 | int32_t index, |
michael@0 | 864 | UChar *value, |
michael@0 | 865 | int32_t valueLength, |
michael@0 | 866 | UErrorCode *status) |
michael@0 | 867 | { |
michael@0 | 868 | verifyIsSimpleDateFormat(format, status); |
michael@0 | 869 | if(U_FAILURE(*status)) return; |
michael@0 | 870 | |
michael@0 | 871 | DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols(); |
michael@0 | 872 | |
michael@0 | 873 | switch(type) { |
michael@0 | 874 | case UDAT_ERAS: |
michael@0 | 875 | DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status); |
michael@0 | 876 | break; |
michael@0 | 877 | |
michael@0 | 878 | case UDAT_ERA_NAMES: |
michael@0 | 879 | DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status); |
michael@0 | 880 | break; |
michael@0 | 881 | |
michael@0 | 882 | case UDAT_MONTHS: |
michael@0 | 883 | DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status); |
michael@0 | 884 | break; |
michael@0 | 885 | |
michael@0 | 886 | case UDAT_SHORT_MONTHS: |
michael@0 | 887 | DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status); |
michael@0 | 888 | break; |
michael@0 | 889 | |
michael@0 | 890 | case UDAT_NARROW_MONTHS: |
michael@0 | 891 | DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status); |
michael@0 | 892 | break; |
michael@0 | 893 | |
michael@0 | 894 | case UDAT_STANDALONE_MONTHS: |
michael@0 | 895 | DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status); |
michael@0 | 896 | break; |
michael@0 | 897 | |
michael@0 | 898 | case UDAT_STANDALONE_SHORT_MONTHS: |
michael@0 | 899 | DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status); |
michael@0 | 900 | break; |
michael@0 | 901 | |
michael@0 | 902 | case UDAT_STANDALONE_NARROW_MONTHS: |
michael@0 | 903 | DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status); |
michael@0 | 904 | break; |
michael@0 | 905 | |
michael@0 | 906 | case UDAT_WEEKDAYS: |
michael@0 | 907 | DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status); |
michael@0 | 908 | break; |
michael@0 | 909 | |
michael@0 | 910 | case UDAT_SHORT_WEEKDAYS: |
michael@0 | 911 | DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status); |
michael@0 | 912 | break; |
michael@0 | 913 | |
michael@0 | 914 | case UDAT_SHORTER_WEEKDAYS: |
michael@0 | 915 | DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status); |
michael@0 | 916 | break; |
michael@0 | 917 | |
michael@0 | 918 | case UDAT_NARROW_WEEKDAYS: |
michael@0 | 919 | DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status); |
michael@0 | 920 | break; |
michael@0 | 921 | |
michael@0 | 922 | case UDAT_STANDALONE_WEEKDAYS: |
michael@0 | 923 | DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status); |
michael@0 | 924 | break; |
michael@0 | 925 | |
michael@0 | 926 | case UDAT_STANDALONE_SHORT_WEEKDAYS: |
michael@0 | 927 | DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status); |
michael@0 | 928 | break; |
michael@0 | 929 | |
michael@0 | 930 | case UDAT_STANDALONE_SHORTER_WEEKDAYS: |
michael@0 | 931 | DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status); |
michael@0 | 932 | break; |
michael@0 | 933 | |
michael@0 | 934 | case UDAT_STANDALONE_NARROW_WEEKDAYS: |
michael@0 | 935 | DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status); |
michael@0 | 936 | break; |
michael@0 | 937 | |
michael@0 | 938 | case UDAT_QUARTERS: |
michael@0 | 939 | DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status); |
michael@0 | 940 | break; |
michael@0 | 941 | |
michael@0 | 942 | case UDAT_SHORT_QUARTERS: |
michael@0 | 943 | DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status); |
michael@0 | 944 | break; |
michael@0 | 945 | |
michael@0 | 946 | case UDAT_STANDALONE_QUARTERS: |
michael@0 | 947 | DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status); |
michael@0 | 948 | break; |
michael@0 | 949 | |
michael@0 | 950 | case UDAT_STANDALONE_SHORT_QUARTERS: |
michael@0 | 951 | DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status); |
michael@0 | 952 | break; |
michael@0 | 953 | |
michael@0 | 954 | case UDAT_AM_PMS: |
michael@0 | 955 | DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status); |
michael@0 | 956 | break; |
michael@0 | 957 | |
michael@0 | 958 | case UDAT_LOCALIZED_CHARS: |
michael@0 | 959 | DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status); |
michael@0 | 960 | break; |
michael@0 | 961 | |
michael@0 | 962 | default: |
michael@0 | 963 | *status = U_UNSUPPORTED_ERROR; |
michael@0 | 964 | break; |
michael@0 | 965 | |
michael@0 | 966 | } |
michael@0 | 967 | } |
michael@0 | 968 | |
michael@0 | 969 | U_CAPI const char* U_EXPORT2 |
michael@0 | 970 | udat_getLocaleByType(const UDateFormat *fmt, |
michael@0 | 971 | ULocDataLocaleType type, |
michael@0 | 972 | UErrorCode* status) |
michael@0 | 973 | { |
michael@0 | 974 | if (fmt == NULL) { |
michael@0 | 975 | if (U_SUCCESS(*status)) { |
michael@0 | 976 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 977 | } |
michael@0 | 978 | return NULL; |
michael@0 | 979 | } |
michael@0 | 980 | return ((Format*)fmt)->getLocaleID(type, *status); |
michael@0 | 981 | } |
michael@0 | 982 | |
michael@0 | 983 | |
michael@0 | 984 | U_CAPI void U_EXPORT2 |
michael@0 | 985 | udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status) |
michael@0 | 986 | { |
michael@0 | 987 | verifyIsSimpleDateFormat(fmt, status); |
michael@0 | 988 | if (U_FAILURE(*status)) { |
michael@0 | 989 | return; |
michael@0 | 990 | } |
michael@0 | 991 | ((SimpleDateFormat*)fmt)->setContext(value, *status); |
michael@0 | 992 | } |
michael@0 | 993 | |
michael@0 | 994 | U_CAPI UDisplayContext U_EXPORT2 |
michael@0 | 995 | udat_getContext(UDateFormat* fmt, UDisplayContextType type, UErrorCode* status) |
michael@0 | 996 | { |
michael@0 | 997 | verifyIsSimpleDateFormat(fmt, status); |
michael@0 | 998 | if (U_FAILURE(*status)) { |
michael@0 | 999 | return (UDisplayContext)0; |
michael@0 | 1000 | } |
michael@0 | 1001 | return ((SimpleDateFormat*)fmt)->getContext(type, *status); |
michael@0 | 1002 | } |
michael@0 | 1003 | |
michael@0 | 1004 | |
michael@0 | 1005 | /** |
michael@0 | 1006 | * Verify that fmt is a RelativeDateFormat. Invalid error if not. |
michael@0 | 1007 | * @param fmt the UDateFormat, definitely a DateFormat, maybe something else |
michael@0 | 1008 | * @param status error code, will be set to failure if there is a familure or the fmt is NULL. |
michael@0 | 1009 | */ |
michael@0 | 1010 | static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) { |
michael@0 | 1011 | if(U_SUCCESS(*status) && |
michael@0 | 1012 | dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { |
michael@0 | 1013 | *status = U_ILLEGAL_ARGUMENT_ERROR; |
michael@0 | 1014 | } |
michael@0 | 1015 | } |
michael@0 | 1016 | |
michael@0 | 1017 | |
michael@0 | 1018 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 1019 | udat_toPatternRelativeDate(const UDateFormat *fmt, |
michael@0 | 1020 | UChar *result, |
michael@0 | 1021 | int32_t resultLength, |
michael@0 | 1022 | UErrorCode *status) |
michael@0 | 1023 | { |
michael@0 | 1024 | verifyIsRelativeDateFormat(fmt, status); |
michael@0 | 1025 | if(U_FAILURE(*status)) return -1; |
michael@0 | 1026 | |
michael@0 | 1027 | UnicodeString datePattern; |
michael@0 | 1028 | if(!(result==NULL && resultLength==0)) { |
michael@0 | 1029 | // NULL destination for pure preflighting: empty dummy string |
michael@0 | 1030 | // otherwise, alias the destination buffer |
michael@0 | 1031 | datePattern.setTo(result, 0, resultLength); |
michael@0 | 1032 | } |
michael@0 | 1033 | ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); |
michael@0 | 1034 | return datePattern.extract(result, resultLength, *status); |
michael@0 | 1035 | } |
michael@0 | 1036 | |
michael@0 | 1037 | U_CAPI int32_t U_EXPORT2 |
michael@0 | 1038 | udat_toPatternRelativeTime(const UDateFormat *fmt, |
michael@0 | 1039 | UChar *result, |
michael@0 | 1040 | int32_t resultLength, |
michael@0 | 1041 | UErrorCode *status) |
michael@0 | 1042 | { |
michael@0 | 1043 | verifyIsRelativeDateFormat(fmt, status); |
michael@0 | 1044 | if(U_FAILURE(*status)) return -1; |
michael@0 | 1045 | |
michael@0 | 1046 | UnicodeString timePattern; |
michael@0 | 1047 | if(!(result==NULL && resultLength==0)) { |
michael@0 | 1048 | // NULL destination for pure preflighting: empty dummy string |
michael@0 | 1049 | // otherwise, alias the destination buffer |
michael@0 | 1050 | timePattern.setTo(result, 0, resultLength); |
michael@0 | 1051 | } |
michael@0 | 1052 | ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); |
michael@0 | 1053 | return timePattern.extract(result, resultLength, *status); |
michael@0 | 1054 | } |
michael@0 | 1055 | |
michael@0 | 1056 | U_CAPI void U_EXPORT2 |
michael@0 | 1057 | udat_applyPatternRelative(UDateFormat *format, |
michael@0 | 1058 | const UChar *datePattern, |
michael@0 | 1059 | int32_t datePatternLength, |
michael@0 | 1060 | const UChar *timePattern, |
michael@0 | 1061 | int32_t timePatternLength, |
michael@0 | 1062 | UErrorCode *status) |
michael@0 | 1063 | { |
michael@0 | 1064 | verifyIsRelativeDateFormat(format, status); |
michael@0 | 1065 | if(U_FAILURE(*status)) return; |
michael@0 | 1066 | const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength); |
michael@0 | 1067 | const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength); |
michael@0 | 1068 | ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); |
michael@0 | 1069 | } |
michael@0 | 1070 | |
michael@0 | 1071 | #endif /* #if !UCONFIG_NO_FORMATTING */ |