U_CAPI int32_t U_EXPORT2
unum_format(    const    UNumberFormat*    fmt,
        int32_t           number,
        UChar*            result,
        int32_t           resultLength,
        UFieldPosition    *pos,
        UErrorCode*       status)
{
        return unum_formatInt64(fmt, number, result, resultLength, pos, status);
}
예제 #2
0
static Variant doFormat(NumberFormatter *obj, int64_t val) {
  UErrorCode error = U_ZERO_ERROR;
  uint32_t len = unum_formatInt64(obj->formatter(), val,
                                  nullptr, 0, nullptr, &error);
  if (error != U_BUFFER_OVERFLOW_ERROR) {
    obj->setError(error);
    return false;
  }
  error = U_ZERO_ERROR;
  icu::UnicodeString out;
  len = unum_formatInt64(obj->formatter(), val,
                         out.getBuffer(len + 1), len + 1,
                         nullptr, &error);
  NUMFMT_CHECK(obj, error, false);
  out.releaseBuffer(len);
  error = U_ZERO_ERROR;
  String ret(u8(out, error));
  NUMFMT_CHECK(obj, error, false);
  return ret;
}
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);
}
/* 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);
}
예제 #5
0
파일: icu_numeric.c 프로젝트: richo/icu
/**
 *  call-seq:
 *     23874.localize(:decimal, 'es_ES') => 23.874
 */
VALUE rb_numeric_localize(int argc, VALUE *argv, VALUE self)
{
	VALUE style, options;
	UNumberFormatStyle formatStyle;
	char *locale = NULL;

	UNumberFormat *format;
	UErrorCode status;

	UChar result[256];
	/* arguments */
	rb_scan_args(argc, argv, "02", &style, &options);
	if (style == Qnil) {
		formatStyle = UNUM_DECIMAL;
	} else {
		ID style_ID;

		Check_Type(style, T_SYMBOL);
		style_ID = SYM2ID(style);
		if (style_ID == rb_intern("decimal")) {
			formatStyle = UNUM_DECIMAL;
		} else if (style_ID == rb_intern("currency")) {
			formatStyle = UNUM_CURRENCY;
		} else if (style_ID == rb_intern("percent")) {
			formatStyle = UNUM_PERCENT;
		} else if (style_ID == rb_intern("scientific")) {
			formatStyle = UNUM_SCIENTIFIC;
		} else if (style_ID == rb_intern("spellout")) {
			formatStyle = UNUM_SPELLOUT;
		} else {
			rb_raise(rb_eArgError, "unsupported format style %s", rb_id2name(style_ID));
		}
	}
	if (options != Qnil) {
		VALUE rb_locale;

		Check_Type(options, T_HASH);
		rb_locale = rb_hash_aref(options, ID2SYM(rb_intern("locale")));
		if (rb_locale != Qnil) {
			locale = StringValuePtr(rb_locale);
		}
	}
	/* formatter */
	status = U_ZERO_ERROR;
    format = unum_open(formatStyle, NULL, 0, locale, NULL, &status);
    RAISE_ON_ERROR(status);
    /* set format attributes */
	if (options != Qnil) {
		VALUE currency, precision, round_mode, round_increment;

		switch (formatStyle) {
			case UNUM_CURRENCY:
				currency = rb_hash_aref(options, ID2SYM(rb_intern("currency")));
				if (currency != Qnil) {
					UChar *uStr;
					int32_t uStrLen;

					uStr = u_strFromRString(currency, &uStrLen);
					status = U_ZERO_ERROR;
					unum_setTextAttribute(format, UNUM_CURRENCY_CODE, uStr, uStrLen, &status);
					RAISE_ON_ERROR(status);
				}
			case UNUM_DECIMAL:
				/* precision */
				precision = rb_hash_aref(options, ID2SYM(rb_intern("precision")));
				if (precision != Qnil) {
					Check_Type(precision, T_FIXNUM);
					status = U_ZERO_ERROR;
					unum_setAttribute(format, UNUM_FRACTION_DIGITS, NUM2INT(precision));
					RAISE_ON_ERROR(status);
				}

				round_mode = rb_hash_aref(options, ID2SYM(rb_intern("round_mode")));
				if (round_mode != Qnil) {
					ID round_mode_ID;
					UNumberFormatRoundingMode rounding_mode;

					Check_Type(round_mode, T_SYMBOL);
					round_mode_ID = SYM2ID(round_mode);
					if (round_mode_ID == rb_intern("ceil")) {
						rounding_mode = UNUM_ROUND_CEILING;
					} else if (round_mode_ID == rb_intern("floor")) {
						rounding_mode = UNUM_ROUND_FLOOR;
					} else if (round_mode_ID == rb_intern("down")) {
						rounding_mode = UNUM_ROUND_DOWN;
					} else if (round_mode_ID == rb_intern("up")) {
						rounding_mode = UNUM_ROUND_UP;
					} else if (round_mode_ID == rb_intern("halfeven")) {
						rounding_mode = UNUM_FOUND_HALFEVEN;
					} else if (round_mode_ID == rb_intern("halfdown")) {
						rounding_mode = UNUM_ROUND_HALFDOWN;
					} else if (round_mode_ID == rb_intern("halfup")) {
						rounding_mode = UNUM_ROUND_HALFUP;
					} else {
						rb_raise(rb_eArgError, "unsupported rounding mode '%s'", rb_id2name(round_mode_ID));
					}
					status = U_ZERO_ERROR;
					unum_setAttribute(format, UNUM_ROUNDING_MODE, rounding_mode);
					RAISE_ON_ERROR(status);
				}
				round_increment = rb_hash_aref(options, ID2SYM(rb_intern("round_increment")));
				if (round_increment != Qnil) {
					Check_Type(round_increment, T_FLOAT);
					status = U_ZERO_ERROR;
					unum_setDoubleAttribute(format, UNUM_ROUNDING_INCREMENT, NUM2DBL(round_increment));
					RAISE_ON_ERROR(status);
				}
		}
	}
	/* format */
	status = U_ZERO_ERROR;
    switch (TYPE(self)) {
    	case T_FIXNUM:
    		unum_format(format, NUM2INT(self), result, 256, NULL, &status);
    		break;
    	case T_FLOAT:
    		unum_formatDouble(format, NUM2DBL(self), result, 256, NULL, &status);
    		break;
    	case T_BIGNUM:
			unum_formatInt64(format, rb_big2ll(self), result, 256, NULL, &status);
    		break;

    }
    RAISE_ON_ERROR(status);
    /* free resources */
    unum_close(format);

    return u_strToRString(result, -1);
}