• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2017 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 package ohos.global.icu.number;
5 
6 import java.math.BigInteger;
7 import java.text.Format;
8 import java.util.Objects;
9 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
10 
11 import ohos.global.icu.impl.FormattedStringBuilder;
12 import ohos.global.icu.impl.StandardPlural;
13 import ohos.global.icu.impl.number.DecimalQuantity;
14 import ohos.global.icu.impl.number.DecimalQuantity_DualStorageBCD;
15 import ohos.global.icu.impl.number.LocalizedNumberFormatterAsFormat;
16 import ohos.global.icu.impl.number.MacroProps;
17 import ohos.global.icu.math.BigDecimal;
18 import ohos.global.icu.util.CurrencyAmount;
19 import ohos.global.icu.util.Measure;
20 import ohos.global.icu.util.MeasureUnit;
21 
22 /**
23  * A NumberFormatter that has a locale associated with it; this means .format() methods are available.
24  *
25  * Instances of this class are immutable and thread-safe.
26  *
27  * @see NumberFormatter
28  * @see NumberFormatter
29  */
30 public class LocalizedNumberFormatter extends NumberFormatterSettings<LocalizedNumberFormatter> {
31 
32     static final AtomicLongFieldUpdater<LocalizedNumberFormatter> callCount = AtomicLongFieldUpdater
33             .newUpdater(LocalizedNumberFormatter.class, "callCountInternal");
34 
35     volatile long callCountInternal; // do not access directly; use callCount instead
36     volatile LocalizedNumberFormatter savedWithUnit;
37     volatile NumberFormatterImpl compiled;
38 
LocalizedNumberFormatter(NumberFormatterSettings<?> parent, int key, Object value)39     LocalizedNumberFormatter(NumberFormatterSettings<?> parent, int key, Object value) {
40         super(parent, key, value);
41     }
42 
43     /**
44      * Format the given byte, short, int, or long to a string using the settings specified in the
45      * NumberFormatter fluent setting chain.
46      *
47      * @param input
48      *            The number to format.
49      * @return A FormattedNumber object; call .toString() to get the string.
50      * @see NumberFormatter
51      */
format(long input)52     public FormattedNumber format(long input) {
53         return format(new DecimalQuantity_DualStorageBCD(input));
54     }
55 
56     /**
57      * Format the given float or double to a string using the settings specified in the NumberFormatter
58      * fluent setting chain.
59      *
60      * @param input
61      *            The number to format.
62      * @return A FormattedNumber object; call .toString() to get the string.
63      * @see NumberFormatter
64      */
format(double input)65     public FormattedNumber format(double input) {
66         return format(new DecimalQuantity_DualStorageBCD(input));
67     }
68 
69     /**
70      * Format the given {@link BigInteger}, {@link BigDecimal}, or other {@link Number} to a string using
71      * the settings specified in the NumberFormatter fluent setting chain.
72      *
73      * @param input
74      *            The number to format.
75      * @return A FormattedNumber object; call .toString() to get the string.
76      * @see NumberFormatter
77      */
format(Number input)78     public FormattedNumber format(Number input) {
79         return format(new DecimalQuantity_DualStorageBCD(input));
80     }
81 
82     /**
83      * Format the given {@link Measure} or {@link CurrencyAmount} to a string using the settings
84      * specified in the NumberFormatter fluent setting chain.
85      *
86      * <p>
87      * The unit specified here overrides any unit that may have been specified in the setter chain. This
88      * method is intended for cases when each input to the number formatter has a different unit.
89      *
90      * @param input
91      *            The number to format.
92      * @return A FormattedNumber object; call .toString() to get the string.
93      * @see NumberFormatter
94      */
format(Measure input)95     public FormattedNumber format(Measure input) {
96         DecimalQuantity fq = new DecimalQuantity_DualStorageBCD(input.getNumber());
97         MeasureUnit unit = input.getUnit();
98         FormattedStringBuilder string = new FormattedStringBuilder();
99         formatImpl(fq, unit, string);
100         return new FormattedNumber(string, fq);
101     }
102 
103     /**
104      * Creates a representation of this LocalizedNumberFormat as a {@link java.text.Format}, enabling the
105      * use of this number formatter with APIs that need an object of that type, such as MessageFormat.
106      * <p>
107      * This API is not intended to be used other than for enabling API compatibility. The {@link #format}
108      * methods should normally be used when formatting numbers, not the Format object returned by this
109      * method.
110      *
111      * @return A Format wrapping this LocalizedNumberFormatter.
112      * @see NumberFormatter
113      */
toFormat()114     public Format toFormat() {
115         return new LocalizedNumberFormatterAsFormat(this, resolve().loc);
116     }
117 
118     /** Helper method that creates a FormattedStringBuilder and formats. */
format(DecimalQuantity fq)119     private FormattedNumber format(DecimalQuantity fq) {
120         FormattedStringBuilder string = new FormattedStringBuilder();
121         formatImpl(fq, string);
122         return new FormattedNumber(string, fq);
123     }
124 
125     /**
126      * This is the core entrypoint to the number formatting pipeline. It performs self-regulation: a
127      * static code path for the first few calls, and compiling a more efficient data structure if called
128      * repeatedly.
129      *
130      * <p>
131      * This function is very hot, being called in every call to the number formatting pipeline.
132      *
133      * @param fq
134      *            The quantity to be formatted.
135      * @param string
136      *            The string builder into which to insert the result.
137      *
138      * @deprecated ICU 60 This API is ICU internal only.
139      * @hide draft / provisional / internal are hidden on OHOS
140      */
141     @Deprecated
formatImpl(DecimalQuantity fq, FormattedStringBuilder string)142     public void formatImpl(DecimalQuantity fq, FormattedStringBuilder string) {
143         if (computeCompiled()) {
144             compiled.format(fq, string);
145         } else {
146             NumberFormatterImpl.formatStatic(resolve(), fq, string);
147         }
148     }
149 
150     /**
151      * Version of above for unit override.
152      *
153      * @deprecated ICU 67 This API is ICU internal only.
154      * @hide draft / provisional / internal are hidden on OHOS
155      */
156     @Deprecated
formatImpl(DecimalQuantity fq, MeasureUnit unit, FormattedStringBuilder string)157     public void formatImpl(DecimalQuantity fq, MeasureUnit unit, FormattedStringBuilder string) {
158         // Use this formatter if possible
159         if (Objects.equals(resolve().unit, unit)) {
160             formatImpl(fq, string);
161             return;
162         }
163         // This mechanism saves the previously used unit, so if the user calls this method with the
164         // same unit multiple times in a row, they get a more efficient code path.
165         LocalizedNumberFormatter withUnit = savedWithUnit;
166         if (withUnit == null || !Objects.equals(withUnit.resolve().unit, unit)) {
167             withUnit = new LocalizedNumberFormatter(this, KEY_UNIT, unit);
168             savedWithUnit = withUnit;
169         }
170         withUnit.formatImpl(fq, string);
171     }
172 
173     /**
174      * @deprecated This API is ICU internal only. Use {@link FormattedNumber#nextPosition}
175      *             for related functionality.
176      * @hide draft / provisional / internal are hidden on OHOS
177      */
178     @Deprecated
getAffixImpl(boolean isPrefix, boolean isNegative)179     public String getAffixImpl(boolean isPrefix, boolean isNegative) {
180         FormattedStringBuilder string = new FormattedStringBuilder();
181         byte signum = (byte) (isNegative ? -1 : 1);
182         // Always return affixes for plural form OTHER.
183         StandardPlural plural = StandardPlural.OTHER;
184         int prefixLength;
185         if (computeCompiled()) {
186             prefixLength = compiled.getPrefixSuffix(signum, plural, string);
187         } else {
188             prefixLength = NumberFormatterImpl.getPrefixSuffixStatic(resolve(), signum, plural, string);
189         }
190         if (isPrefix) {
191             return string.subSequence(0, prefixLength).toString();
192         } else {
193             return string.subSequence(prefixLength, string.length()).toString();
194         }
195     }
196 
computeCompiled()197     private boolean computeCompiled() {
198         MacroProps macros = resolve();
199         // NOTE: In Java, the atomic increment logic is slightly different than ICU4C.
200         // It seems to be more efficient to make just one function call instead of two.
201         // Further benchmarking is required.
202         long currentCount = callCount.incrementAndGet(this);
203         if (currentCount == macros.threshold.longValue()) {
204             compiled = new NumberFormatterImpl(macros);
205             return true;
206         } else if (compiled != null) {
207             return true;
208         } else {
209             return false;
210         }
211     }
212 
213     @Override
create(int key, Object value)214     LocalizedNumberFormatter create(int key, Object value) {
215         return new LocalizedNumberFormatter(this, key, value);
216     }
217 }