/* GENERATED SOURCE. DO NOT MODIFY. */ // © 2017 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html package android.icu.number; import java.math.BigInteger; import java.text.Format; import java.util.Objects; import java.util.concurrent.atomic.AtomicLongFieldUpdater; import android.icu.impl.FormattedStringBuilder; import android.icu.impl.StandardPlural; import android.icu.impl.number.DecimalQuantity; import android.icu.impl.number.DecimalQuantity_DualStorageBCD; import android.icu.impl.number.LocalizedNumberFormatterAsFormat; import android.icu.impl.number.MacroProps; import android.icu.impl.number.MicroProps; import android.icu.math.BigDecimal; import android.icu.util.CurrencyAmount; import android.icu.util.Measure; import android.icu.util.MeasureUnit; /** * A NumberFormatter that has a locale associated with it; this means .format() methods are available. * * Instances of this class are immutable and thread-safe. * * @see NumberFormatter * @see NumberFormatter */ public class LocalizedNumberFormatter extends NumberFormatterSettings { static final AtomicLongFieldUpdater callCount = AtomicLongFieldUpdater .newUpdater(LocalizedNumberFormatter.class, "callCountInternal"); volatile long callCountInternal; // do not access directly; use callCount instead volatile LocalizedNumberFormatter savedWithUnit; volatile NumberFormatterImpl compiled; LocalizedNumberFormatter(NumberFormatterSettings parent, int key, Object value) { super(parent, key, value); } /** * Format the given byte, short, int, or long to a string using the settings specified in the * NumberFormatter fluent setting chain. * * @param input * The number to format. * @return A FormattedNumber object; call .toString() to get the string. * @see NumberFormatter */ public FormattedNumber format(long input) { return format(new DecimalQuantity_DualStorageBCD(input)); } /** * Format the given float or double to a string using the settings specified in the NumberFormatter * fluent setting chain. * * @param input * The number to format. * @return A FormattedNumber object; call .toString() to get the string. * @see NumberFormatter */ public FormattedNumber format(double input) { return format(new DecimalQuantity_DualStorageBCD(input)); } /** * Format the given {@link BigInteger}, {@link BigDecimal}, or other {@link Number} to a string using * the settings specified in the NumberFormatter fluent setting chain. * * @param input * The number to format. * @return A FormattedNumber object; call .toString() to get the string. * @see NumberFormatter */ public FormattedNumber format(Number input) { return format(new DecimalQuantity_DualStorageBCD(input)); } /** * Format the given {@link Measure} or {@link CurrencyAmount} to a string using the settings * specified in the NumberFormatter fluent setting chain. * *

* The unit specified here overrides any unit that may have been specified in the setter chain. This * method is intended for cases when each input to the number formatter has a different unit. * * @param input * The number to format. * @return A FormattedNumber object; call .toString() to get the string. * @see NumberFormatter */ public FormattedNumber format(Measure input) { DecimalQuantity fq = new DecimalQuantity_DualStorageBCD(input.getNumber()); MeasureUnit unit = input.getUnit(); FormattedStringBuilder string = new FormattedStringBuilder(); MicroProps micros = formatImpl(fq, unit, string); return new FormattedNumber(string, fq, micros.outputUnit, micros.gender); } /** * Creates a representation of this LocalizedNumberFormat as a {@link java.text.Format}, enabling the * use of this number formatter with APIs that need an object of that type, such as MessageFormat. *

* This API is not intended to be used other than for enabling API compatibility. The {@link #format} * methods should normally be used when formatting numbers, not the Format object returned by this * method. * * @return A Format wrapping this LocalizedNumberFormatter. * @see NumberFormatter */ public Format toFormat() { return new LocalizedNumberFormatterAsFormat(this, resolve().loc); } /** * Disassociate the locale from this formatter. * * @return The fluent chain. * @hide draft / provisional / internal are hidden on Android */ public UnlocalizedNumberFormatter withoutLocale() { return new UnlocalizedNumberFormatter(this, KEY_LOCALE, null); } /** * Helper method that creates a FormattedStringBuilder and formats. */ private FormattedNumber format(DecimalQuantity fq) { FormattedStringBuilder string = new FormattedStringBuilder(); MicroProps micros = formatImpl(fq, string); return new FormattedNumber(string, fq, micros.outputUnit, micros.gender); } /** * This is the core entrypoint to the number formatting pipeline. It performs self-regulation: a * static code path for the first few calls, and compiling a more efficient data structure if called * repeatedly. * *

* This function is very hot, being called in every call to the number formatting pipeline. * * @param fq * The quantity to be formatted. * @param string * The string builder into which to insert the result. * * @deprecated ICU 60 This API is ICU internal only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public MicroProps formatImpl(DecimalQuantity fq, FormattedStringBuilder string) { if (computeCompiled()) { return compiled.format(fq, string); } return NumberFormatterImpl.formatStatic(resolve(), fq, string); } /** * Version of above for unit override. * * @deprecated ICU 67 This API is ICU internal only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public MicroProps formatImpl(DecimalQuantity fq, MeasureUnit unit, FormattedStringBuilder string) { // Use this formatter if possible if (Objects.equals(resolve().unit, unit)) { return formatImpl(fq, string); } // This mechanism saves the previously used unit, so if the user calls this method with the // same unit multiple times in a row, they get a more efficient code path. LocalizedNumberFormatter withUnit = savedWithUnit; if (withUnit == null || !Objects.equals(withUnit.resolve().unit, unit)) { withUnit = new LocalizedNumberFormatter(this, KEY_UNIT, unit); savedWithUnit = withUnit; } return withUnit.formatImpl(fq, string); } /** * @deprecated This API is ICU internal only. Use {@link FormattedNumber#nextPosition} * for related functionality. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public String getAffixImpl(boolean isPrefix, boolean isNegative) { FormattedStringBuilder string = new FormattedStringBuilder(); byte signum = (byte) (isNegative ? -1 : 1); // Always return affixes for plural form OTHER. StandardPlural plural = StandardPlural.OTHER; int prefixLength; if (computeCompiled()) { prefixLength = compiled.getPrefixSuffix(signum, plural, string); } else { prefixLength = NumberFormatterImpl.getPrefixSuffixStatic(resolve(), signum, plural, string); } if (isPrefix) { return string.subSequence(0, prefixLength).toString(); } else { return string.subSequence(prefixLength, string.length()).toString(); } } private boolean computeCompiled() { MacroProps macros = resolve(); // NOTE: In Java, the atomic increment logic is slightly different than ICU4C. // It seems to be more efficient to make just one function call instead of two. // Further benchmarking is required. long currentCount = callCount.incrementAndGet(this); if (currentCount == macros.threshold.longValue()) { compiled = new NumberFormatterImpl(macros); return true; } else if (compiled != null) { return true; } else { return false; } } @Override LocalizedNumberFormatter create(int key, Object value) { return new LocalizedNumberFormatter(this, key, value); } }