static bool HHVM_METHOD(NumberFormatter, setAttribute, int64_t attr, const Variant& value) { 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): unum_setAttribute(obj->formatter(), (UNumberFormatAttribute)attr, value.toInt64()); return true; case UNUM(ROUNDING_INCREMENT): unum_setDoubleAttribute(obj->formatter(), (UNumberFormatAttribute)attr, value.toDouble()); return true; default: obj->setError(U_UNSUPPORTED_ERROR); return false; } }
static Variant HHVM_METHOD(NumberFormatter, format, const Variant& value, int64_t type) { NUMFMT_GET(obj, this_, false); Variant num(value); // De-const int64_t ival = 0; double dval = 0.0; DataType dt = num.toNumeric(ival, dval, true); if (dt == KindOfInt64) { num = ival; } else if (dt == KindOfDouble) { num = dval; } else { num = value.toInt64(); } if (type == UNUM(TYPE_DEFAULT)) { if (value.isInteger()) { type = UNUM(TYPE_INT64); } else if (value.isDouble()) { type = UNUM(TYPE_DOUBLE); } } if (type == UNUM(TYPE_DOUBLE)) { return doFormat(obj, num.toDouble()); } else { return doFormat(obj, num.toInt64()); } }
static Variant HHVM_METHOD(NumberFormatter, parse, const String& value, int64_t type, VRefParam position) { NUMFMT_GET(obj, this_, false); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString val(u16(value, error)); NUMFMT_CHECK(obj, error, false); Variant ret; int32_t pos = position.toInt64(); error = U_ZERO_ERROR; switch (type) { case UNUM(TYPE_INT32): ret = unum_parse(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; case UNUM(TYPE_INT64): ret = unum_parseInt64(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; case UNUM(TYPE_DOUBLE): ret = unum_parseDouble(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; default: obj->setError(U_UNSUPPORTED_ERROR); return false; } NUMFMT_CHECK(obj, error, false); position = pos; return ret; }
static String HHVM_METHOD(NumberFormatter, getLocale, int64_t type) { NUMFMT_GET(obj, this_, String()); UErrorCode error = U_ZERO_ERROR; const char *loc = unum_getLocaleByType(obj->formatter(), (ULocDataLocaleType)type, &error); NUMFMT_CHECK(obj, error, String()); return String(loc, CopyString); }
static bool HHVM_METHOD(NumberFormatter, setTextAttribute, int64_t attr, const String& value) { NUMFMT_GET(obj, this_, false); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString val(u16(value, error)); NUMFMT_CHECK(obj, error, false); unum_setTextAttribute(obj->formatter(), (UNumberFormatTextAttribute)attr, val.getBuffer(), val.length(), &error); NUMFMT_CHECK(obj, error, false); return true; }
static bool HHVM_METHOD(NumberFormatter, setPattern, const String& pattern) { NUMFMT_GET(obj, this_, false); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString pat(u16(pattern, error)); NUMFMT_CHECK(obj, error, false); error = U_ZERO_ERROR; unum_applyPattern(obj->formatter(), 0, pat.getBuffer(), pat.length(), nullptr, &error); NUMFMT_CHECK(obj, error, false); return true; }
static bool HHVM_METHOD(NumberFormatter, setSymbol, int64_t attr, const String& value) { NUMFMT_GET(obj, this_, false); if (attr >= UNUM_FORMAT_SYMBOL_COUNT || attr < 0) { obj->setError(U_ILLEGAL_ARGUMENT_ERROR, "numfmt_set_symbol: invalid symbol value"); return false; } UErrorCode error = U_ZERO_ERROR; icu::UnicodeString val(u16(value, error)); NUMFMT_CHECK(obj, error, false); error = U_ZERO_ERROR; unum_setSymbol(obj->formatter(), (UNumberFormatSymbol)attr, val.getBuffer(), val.length(), &error); NUMFMT_CHECK(obj, error, false); return true; }
static String HHVM_METHOD(NumberFormatter, getPattern) { NUMFMT_GET(obj, this_, String()); UErrorCode error = U_ZERO_ERROR; int32_t len = unum_toPattern(obj->formatter(), 0, nullptr, 0, &error); if (error != U_BUFFER_OVERFLOW_ERROR) { obj->setError(error); return String(); } icu::UnicodeString out; error = U_ZERO_ERROR; len = unum_toPattern(obj->formatter(), 0, out.getBuffer(len + 1), len + 1, &error); NUMFMT_CHECK(obj, error, String()); out.releaseBuffer(len); String ret(u8(out, error)); NUMFMT_CHECK(obj, error, String()); return ret; }
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; } }
static Variant HHVM_METHOD(NumberFormatter, parseCurrency, const String& value, VRefParam currency, VRefParam position) { NUMFMT_GET(obj, this_, false); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString val(u16(value, error)); NUMFMT_CHECK(obj, error, false); int32_t pos = position.toInt64(); UChar cur[5] = {0}; error = U_ZERO_ERROR; double parsed = unum_parseDoubleCurrency(obj->formatter(), val.getBuffer(), val.length(), &pos, cur, &error); NUMFMT_CHECK(obj, error, false); position = (int64_t)pos; error = U_ZERO_ERROR; currency = u8(cur, u_strlen(cur), error); NUMFMT_CHECK(obj, error, false); return parsed; }
static String HHVM_METHOD(NumberFormatter, getSymbol, int64_t attr) { NUMFMT_GET(obj, this_, null_string); UErrorCode error = U_ZERO_ERROR; int32_t len = unum_getSymbol(obj->formatter(), (UNumberFormatSymbol)attr, nullptr, 0, &error); if (error != U_BUFFER_OVERFLOW_ERROR) { obj->setError(error); return null_string; } icu::UnicodeString out; error = U_ZERO_ERROR; len = unum_getSymbol(obj->formatter(), (UNumberFormatSymbol)attr, out.getBuffer(len + 1), len + 1, &error); NUMFMT_CHECK(obj, error, null_string); out.releaseBuffer(len); String ret(u8(out, error)); NUMFMT_CHECK(obj, error, null_string); return ret; }
static String HHVM_METHOD(NumberFormatter, formatCurrency, double value, const String& currency) { NUMFMT_GET(obj, this_, String()); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString uCurrency(u16(currency, error)); NUMFMT_CHECK(obj, error, String()); // By default UnicodeString isn't NULL terminated int32_t currencyBuffer_len = uCurrency.length(); UChar *currencyBuffer = uCurrency.getBuffer(currencyBuffer_len + 1); SCOPE_EXIT{ uCurrency.releaseBuffer(currencyBuffer_len + 1); }; currencyBuffer[currencyBuffer_len] = 0; error = U_ZERO_ERROR; uint32_t len = unum_formatDoubleCurrency(obj->formatter(), value, currencyBuffer, nullptr, 0, nullptr, &error); if (error != U_BUFFER_OVERFLOW_ERROR) { obj->setError(error); return String(); } icu::UnicodeString out; error = U_ZERO_ERROR; len = unum_formatDoubleCurrency(obj->formatter(), value, currencyBuffer, out.getBuffer(len + 1), len + 1, nullptr, &error); NUMFMT_CHECK(obj, error, String()); out.releaseBuffer(len); String ret(u8(out, error)); NUMFMT_CHECK(obj, error, String()); return ret; }
static Variant HHVM_METHOD(NumberFormatter, format, const Variant& value, int64_t type) { NUMFMT_GET(obj, this_, false); Variant num(value); // De-const if (!num.isDouble() && !num.isInteger()) { int64_t ival = 0; double dval = 0.0; DataType dt = num.toNumeric(ival, dval, true); if (dt == KindOfInt64) { num = ival; } else if (dt == KindOfDouble) { num = dval; } else { obj->setError(U_ILLEGAL_ARGUMENT_ERROR); return false; } } if (type == UNUM(TYPE_DEFAULT)) { if (value.isInteger()) { type = UNUM(TYPE_INT64); } else if (value.isDouble()) { type = UNUM(TYPE_DOUBLE); } } if ((type == UNUM(TYPE_INT32)) || (type == UNUM(TYPE_INT64))) { return doFormat(obj, num.toInt64()); } else if (type == UNUM(TYPE_DOUBLE)) { return doFormat(obj, num.toDouble()); } else { raise_warning("Unsupported format type %ld", (long)type); return false; } }
static String HHVM_METHOD(NumberFormatter, getErrorMessage) { NUMFMT_GET(obj, this_, String()); return obj->getErrorMessage(); }
static int64_t HHVM_METHOD(NumberFormatter, getErrorCode) { NUMFMT_GET(data, this_, 0); return data->getErrorCode(); }