/*
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);
}
Ejemplo n.º 2
0
//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);
}
Ejemplo n.º 5
0
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;
  }
}
Ejemplo n.º 6
0
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));
}
Ejemplo n.º 7
0
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));
}
Ejemplo n.º 8
0
/* 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);
}