/* PAL Function: GetLocaleInfoGroupingSizes Obtains grouping sizes for decimal and currency Returns 1 for success, 0 otherwise */ extern "C" int32_t GlobalizationNative_GetLocaleInfoGroupingSizes( const UChar* localeName, LocaleNumberData localeGroupingData, int32_t* primaryGroupSize, int32_t* secondaryGroupSize) { UErrorCode status = U_ZERO_ERROR; char locale[ULOC_FULLNAME_CAPACITY]; GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &status); if (U_FAILURE(status)) { return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR); } UNumberFormatStyle style; switch (localeGroupingData) { case Digit: style = UNUM_DECIMAL; break; case Monetary: style = UNUM_CURRENCY; break; default: return UErrorCodeToBool(U_UNSUPPORTED_ERROR); } UNumberFormat* numformat = unum_open(style, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *primaryGroupSize = unum_getAttribute(numformat, UNUM_GROUPING_SIZE); *secondaryGroupSize = unum_getAttribute(numformat, UNUM_SECONDARY_GROUPING_SIZE); unum_close(numformat); } return UErrorCodeToBool(status); }
//static jint NativeDecimalFormat_getAttribute(JNIEnv*, jclass, jint addr, jint javaAttr) { JNIEXPORT jint JNICALL Java_com_ibm_icu4jni_text_NativeDecimalFormat_getAttribute(JNIEnv*, jclass, jint addr, jint javaAttr) { UNumberFormatAttribute attr = static_cast<UNumberFormatAttribute> (javaAttr); return unum_getAttribute(toUNumberFormat(addr), attr); }
static int32_t u_printf_scidbl_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { u_printf_spec_info scidbl_info; double num = args[0].doubleValue; int32_t retVal; memcpy(&scidbl_info, info, sizeof(u_printf_spec_info)); /* determine whether to use 'd', 'e' or 'f' notation */ if (scidbl_info.fPrecision == -1 && num == uprv_trunc(num)) { /* use 'f' notation */ scidbl_info.fSpec = 0x0066; scidbl_info.fPrecision = 0; /* call the double handler */ retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); } else if(num < 0.0001 || (scidbl_info.fPrecision < 1 && 1000000.0 <= num) || (scidbl_info.fPrecision != -1 && num > uprv_pow10(scidbl_info.fPrecision))) { /* use 'e' or 'E' notation */ scidbl_info.fSpec = scidbl_info.fSpec - 2; if (scidbl_info.fPrecision == -1) { scidbl_info.fPrecision = 5; } /* call the scientific handler */ retVal = u_printf_scientific_handler(handler, context, formatBundle, &scidbl_info, args); } else { UNumberFormat *format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); int32_t maxSigDecimalDigits = unum_getAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS); int32_t significantDigits = scidbl_info.fPrecision; /* use 'f' notation */ scidbl_info.fSpec = 0x0066; if (significantDigits == -1) { significantDigits = 6; } unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, TRUE); unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, significantDigits); /* call the double handler */ retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, maxSigDecimalDigits); unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, FALSE); } return retVal; }
static int32_t u_printf_uinteger_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { int64_t num = args[0].int64Value; UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; int32_t minDigits = -1; int32_t resultLen; UErrorCode status = U_ZERO_ERROR; /* TODO: Fix this once uint64_t can be formatted. */ if (info->fIsShort) num &= UINT16_MAX; else if (!info->fIsLongLong) num &= UINT32_MAX; /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* set the minimum integer digits */ if(info->fPrecision != -1) { /* set the minimum # of digits */ minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); } /* To mirror other stdio implementations, we ignore the sign argument */ /* format the number */ resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ if (minDigits != -1) { unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); } return handler->pad_and_justify(context, info, result, resultLen); }
static Variant HHVM_METHOD(NumberFormatter, getAttribute, int64_t attr) { NUMFMT_GET(obj, this_, false); switch (attr) { case UNUM(PARSE_INT_ONLY): case UNUM(GROUPING_USED): case UNUM(DECIMAL_ALWAYS_SHOWN): case UNUM(MAX_INTEGER_DIGITS): case UNUM(MIN_INTEGER_DIGITS): case UNUM(INTEGER_DIGITS): case UNUM(MAX_FRACTION_DIGITS): case UNUM(MIN_FRACTION_DIGITS): case UNUM(FRACTION_DIGITS): case UNUM(MULTIPLIER): case UNUM(GROUPING_SIZE): case UNUM(ROUNDING_MODE): case UNUM(FORMAT_WIDTH): case UNUM(PADDING_POSITION): case UNUM(SECONDARY_GROUPING_SIZE): case UNUM(SIGNIFICANT_DIGITS_USED): case UNUM(MIN_SIGNIFICANT_DIGITS): case UNUM(MAX_SIGNIFICANT_DIGITS): case UNUM(LENIENT_PARSE): { int64_t lval = unum_getAttribute(obj->formatter(), (UNumberFormatAttribute)attr); if (lval == -1) { obj->setError(U_UNSUPPORTED_ERROR); return false; } return lval; } case UNUM(ROUNDING_INCREMENT): { double dval = unum_getDoubleAttribute(obj->formatter(), (UNumberFormatAttribute)attr); if (dval == -1) { obj->setError(U_UNSUPPORTED_ERROR); return false; } return dval; } default: obj->setError(U_UNSUPPORTED_ERROR); return false; } }
int32_t u_sprintf_percent_handler(u_localized_string *output, const u_sprintf_spec_info *info, const ufmt_args *args) { double num = (double) (args[0].doubleValue); UNumberFormat *format; UChar result [USPRINTF_BUFFER_SIZE]; int32_t minDecimalDigits; int32_t maxDecimalDigits; UErrorCode status = U_ZERO_ERROR; /* mask off any necessary bits */ /* if(! info->fIsLongDouble) num &= DBL_MAX;*/ /* get the formatter */ format = u_locbund_getPercentFormat(output->fBundle); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* clone the stream's bundle if it isn't owned */ if(! output->fOwnBundle) { output->fBundle = u_locbund_clone(output->fBundle); output->fOwnBundle = TRUE; format = u_locbund_getPercentFormat(output->fBundle); } /* set the number of decimal digits */ /* save the formatter's state */ minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); if(info->fPrecision != -1) { /* set the # of decimal digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); } else if(info->fPrecision == 0 && ! info->fAlt) { /* no decimal point in this case */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 0); } else if(info->fAlt) { /* '#' means always show decimal point */ /* copy of printf behavior on Solaris - '#' shows 6 digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } else { /* # of decimal digits is 6 if precision not specified */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } /* set whether to show the sign */ u_sprintf_set_sign(format, info, &status); /* format the number */ unum_formatDouble(format, num, result, USPRINTF_BUFFER_SIZE, 0, &status); /* restore the number format */ unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); return u_sprintf_pad_and_justify(output, info, result, u_strlen(result)); }
int32_t u_sprintf_scientific_handler(u_localized_string *output, const u_sprintf_spec_info *info, const ufmt_args *args) { double num = (double) (args[0].doubleValue); UNumberFormat *format; UChar result [USPRINTF_BUFFER_SIZE]; int32_t minDecimalDigits; int32_t maxDecimalDigits; UErrorCode status = U_ZERO_ERROR; UChar srcExpBuf[USPRINTF_SYMBOL_BUFFER_SIZE]; int32_t srcLen, expLen; UChar expBuf[USPRINTF_SYMBOL_BUFFER_SIZE]; /* mask off any necessary bits */ /* if(! info->fIsLongDouble) num &= DBL_MAX;*/ /* get the formatter */ format = u_locbund_getScientificFormat(output->fBundle); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* clone the stream's bundle if it isn't owned */ if(! output->fOwnBundle) { output->fBundle = u_locbund_clone(output->fBundle); output->fOwnBundle = TRUE; format = u_locbund_getScientificFormat(output->fBundle); } srcLen = unum_getSymbol(format, UNUM_EXPONENTIAL_SYMBOL, srcExpBuf, sizeof(srcExpBuf), &status); /* Upper/lower case the e */ if (info->fSpec == (UChar)0x65 /* e */) { expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, output->fBundle->fLocale, &status); } else { expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, output->fBundle->fLocale, &status); } unum_setSymbol(format, UNUM_EXPONENTIAL_SYMBOL, expBuf, expLen, &status); /* set the number of decimal digits */ /* save the formatter's state */ minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); if(info->fPrecision != -1) { /* set the # of decimal digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); } else if(info->fPrecision == 0 && ! info->fAlt) { /* no decimal point in this case */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 0); } else if(info->fAlt) { /* '#' means always show decimal point */ /* copy of printf behavior on Solaris - '#' shows 6 digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } else { /* # of decimal digits is 6 if precision not specified */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } /* set whether to show the sign */ u_sprintf_set_sign(format, info, &status); /* format the number */ unum_formatDouble(format, num, result, USPRINTF_BUFFER_SIZE, 0, &status); /* restore the number format */ unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); /* Since we clone the fBundle and we're only using the scientific format, we don't need to save the old exponent value. */ /*unum_setSymbol(format, UNUM_EXPONENTIAL_SYMBOL, srcExpBuf, srcLen, &status);*/ return u_sprintf_pad_and_justify(output, info, result, u_strlen(result)); }
/* HSYS */ int32_t u_sprintf_integer_handler(u_localized_string *output, const u_sprintf_spec_info *info, const ufmt_args *args) { long num = (long) (args[0].intValue); UNumberFormat *format; UChar result [USPRINTF_BUFFER_SIZE]; int32_t minDigits = -1; UErrorCode status = U_ZERO_ERROR; /* mask off any necessary bits */ if(info->fIsShort) num &= UINT16_MAX; else if(! info->fIsLong || ! info->fIsLongLong) num &= UINT32_MAX; /* get the formatter */ format = u_locbund_getNumberFormat(output->fBundle); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* set the minimum integer digits */ if(info->fPrecision != -1) { /* clone the stream's bundle if it isn't owned */ if(! output->fOwnBundle) { output->fBundle = u_locbund_clone(output->fBundle); output->fOwnBundle = TRUE; format = u_locbund_getNumberFormat(output->fBundle); } /* set the minimum # of digits */ minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); } /* set whether to show the sign */ if(info->fShowSign) { /* clone the stream's bundle if it isn't owned */ if(! output->fOwnBundle) { output->fBundle = u_locbund_clone(output->fBundle); output->fOwnBundle = TRUE; format = u_locbund_getNumberFormat(output->fBundle); } u_sprintf_set_sign(format, info, &status); } /* format the number */ unum_format(format, num, result, USPRINTF_BUFFER_SIZE, 0, &status); /* restore the number format */ if(minDigits != -1) { unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); } return u_sprintf_pad_and_justify(output, info, result, u_strlen(result)); }
static jint NativeDecimalFormat_getAttribute(JNIEnv*, jclass, jlong addr, jint javaAttr) { UNumberFormatAttribute attr = static_cast<UNumberFormatAttribute>(javaAttr); return unum_getAttribute(toUNumberFormat(addr), attr); }
static int32_t u_printf_spellout_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { double num = (double) (args[0].doubleValue); UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; int32_t prefixBufferLen = sizeof(prefixBuffer); int32_t minDecimalDigits; int32_t maxDecimalDigits; int32_t resultLen; UErrorCode status = U_ZERO_ERROR; prefixBuffer[0] = 0; /* mask off any necessary bits */ /* if(! info->fIsLongDouble) num &= DBL_MAX;*/ /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT); /* handle error */ if(format == 0) return 0; /* save the formatter's state */ minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); /* set the appropriate flags and number of decimal digits on the formatter */ if(info->fPrecision != -1) { /* set the # of decimal digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); } else if(info->fAlt) { /* '#' means always show decimal point */ /* copy of printf behavior on Solaris - '#' shows 6 digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } else { /* # of decimal digits is 6 if precision not specified */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } /* set whether to show the sign */ if (info->fShowSign) { u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); } /* format the number */ resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ /* TODO: Is this needed? */ unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); if (info->fShowSign) { /* Reset back to original value regardless of what the error was */ UErrorCode localStatus = U_ZERO_ERROR; u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); } return handler->pad_and_justify(context, info, result, resultLen); }
static int32_t u_printf_scientific_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { double num = (double) (args[0].doubleValue); UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; int32_t prefixBufferLen = sizeof(prefixBuffer); int32_t minDecimalDigits; int32_t maxDecimalDigits; UErrorCode status = U_ZERO_ERROR; UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; int32_t srcLen, expLen; int32_t resultLen; UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; prefixBuffer[0] = 0; /* mask off any necessary bits */ /* if(! info->fIsLongDouble) num &= DBL_MAX;*/ /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ srcLen = unum_getSymbol(format, UNUM_EXPONENTIAL_SYMBOL, srcExpBuf, sizeof(srcExpBuf), &status); /* Upper/lower case the e */ if (info->fSpec == (UChar)0x65 /* e */) { expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, formatBundle->fLocale, &status); } else { expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, formatBundle->fLocale, &status); } unum_setSymbol(format, UNUM_EXPONENTIAL_SYMBOL, expBuf, expLen, &status); /* save the formatter's state */ minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); /* set the appropriate flags and number of decimal digits on the formatter */ if(info->fPrecision != -1) { /* set the # of decimal digits */ if (info->fOrigSpec == (UChar)0x65 /* e */ || info->fOrigSpec == (UChar)0x45 /* E */) { unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); } else { unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, 1); unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, info->fPrecision); } } else if(info->fAlt) { /* '#' means always show decimal point */ /* copy of printf behavior on Solaris - '#' shows 6 digits */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } else { /* # of decimal digits is 6 if precision not specified */ unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); } /* set whether to show the sign */ if (info->fShowSign) { u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); } /* format the number */ resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ /* TODO: Is this needed? */ unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); /* Since we're the only one using the scientific format, we don't need to save the old exponent value. */ /*unum_setSymbol(format, UNUM_EXPONENTIAL_SYMBOL, srcExpBuf, srcLen, &status);*/ if (info->fShowSign) { /* Reset back to original value regardless of what the error was */ UErrorCode localStatus = U_ZERO_ERROR; u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); } return handler->pad_and_justify(context, info, result, resultLen); }
/* HSYS */ static int32_t u_printf_integer_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { int64_t num = args[0].int64Value; UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; int32_t prefixBufferLen = sizeof(prefixBuffer); int32_t minDigits = -1; int32_t resultLen; UErrorCode status = U_ZERO_ERROR; prefixBuffer[0] = 0; /* mask off any necessary bits */ if (info->fIsShort) num = (int16_t)num; else if (!info->fIsLongLong) num = (int32_t)num; /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* set the minimum integer digits */ if(info->fPrecision != -1) { /* set the minimum # of digits */ minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); } /* set whether to show the sign */ if(info->fShowSign) { u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); } /* format the number */ resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ if (minDigits != -1) { unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); } if (info->fShowSign) { /* Reset back to original value regardless of what the error was */ UErrorCode localStatus = U_ZERO_ERROR; u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); } return handler->pad_and_justify(context, info, result, resultLen); }
/* PAL Function: GetLocaleInfoInt Obtains integer locale information Returns 1 for success, 0 otherwise */ extern "C" int32_t GlobalizationNative_GetLocaleInfoInt( const UChar* localeName, LocaleNumberData localeNumberData, int32_t* value) { UErrorCode status = U_ZERO_ERROR; char locale[ULOC_FULLNAME_CAPACITY]; GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &status); if (U_FAILURE(status)) { return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR); } switch (localeNumberData) { case LanguageId: *value = uloc_getLCID(locale); break; case MeasurementSystem: status = GetMeasurementSystem(locale, value); break; case FractionalDigitsCount: { UNumberFormat* numformat = unum_open(UNUM_DECIMAL, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); unum_close(numformat); } break; } case NegativeNumberFormat: *value = GetNumberNegativePattern(locale); break; case MonetaryFractionalDigitsCount: { UNumberFormat* numformat = unum_open(UNUM_CURRENCY, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); unum_close(numformat); } break; } case PositiveMonetaryNumberFormat: *value = GetCurrencyPositivePattern(locale); break; case NegativeMonetaryNumberFormat: *value = GetCurrencyNegativePattern(locale); break; case FirstWeekOfYear: { // corresponds to DateTimeFormat.CalendarWeekRule UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) { // values correspond to LOCALE_IFIRSTWEEKOFYEAR int minDaysInWeek = ucal_getAttribute(pCal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK); if (minDaysInWeek == 1) { *value = CalendarWeekRule::FirstDay; } else if (minDaysInWeek == 7) { *value = CalendarWeekRule::FirstFullWeek; } else if (minDaysInWeek >= 4) { *value = CalendarWeekRule::FirstFourDayWeek; } else { status = U_UNSUPPORTED_ERROR; } } break; } case ReadingLayout: { // coresponds to values 0 and 1 in LOCALE_IREADINGLAYOUT (values 2 and 3 not // used in coreclr) // 0 - Left to right (such as en-US) // 1 - Right to left (such as arabic locales) ULayoutType orientation = uloc_getCharacterOrientation(locale, &status); // alternative implementation in ICU 54+ is uloc_isRightToLeft() which // also supports script tags in locale if (U_SUCCESS(status)) { *value = (orientation == ULOC_LAYOUT_RTL) ? 1 : 0; } break; } case FirstDayofWeek: { UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) { *value = ucal_getAttribute(pCal, UCAL_FIRST_DAY_OF_WEEK) - 1; // .NET is 0-based and ICU is 1-based } break; } case NegativePercentFormat: *value = GetPercentNegativePattern(locale); break; case PositivePercentFormat: *value = GetPercentPositivePattern(locale); break; default: status = U_UNSUPPORTED_ERROR; assert(false); break; } return UErrorCodeToBool(status); }