LEFT | RIGHT |
(no file at all) | |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 package com.ibm.icu.number; | 3 package com.ibm.icu.number; |
4 | 4 |
5 import com.ibm.icu.impl.number.CompactData.CompactType; | 5 import com.ibm.icu.impl.number.CompactData.CompactType; |
6 import com.ibm.icu.impl.number.ConstantAffixModifier; | 6 import com.ibm.icu.impl.number.ConstantAffixModifier; |
7 import com.ibm.icu.impl.number.DecimalQuantity; | 7 import com.ibm.icu.impl.number.DecimalQuantity; |
8 import com.ibm.icu.impl.number.LongNameHandler; | 8 import com.ibm.icu.impl.number.LongNameHandler; |
9 import com.ibm.icu.impl.number.MacroProps; | 9 import com.ibm.icu.impl.number.MacroProps; |
10 import com.ibm.icu.impl.number.MicroProps; | 10 import com.ibm.icu.impl.number.MicroProps; |
11 import com.ibm.icu.impl.number.MicroPropsGenerator; | 11 import com.ibm.icu.impl.number.MicroPropsGenerator; |
12 import com.ibm.icu.impl.number.MutablePatternModifier; | 12 import com.ibm.icu.impl.number.MutablePatternModifier; |
13 import com.ibm.icu.impl.number.NumberStringBuilder; | 13 import com.ibm.icu.impl.number.NumberStringBuilder; |
14 import com.ibm.icu.impl.number.Padder; | 14 import com.ibm.icu.impl.number.Padder; |
15 import com.ibm.icu.impl.number.PatternStringParser; | 15 import com.ibm.icu.impl.number.PatternStringParser; |
16 import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo; | 16 import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo; |
17 import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay; | 17 import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay; |
18 import com.ibm.icu.number.NumberFormatter.SignDisplay; | 18 import com.ibm.icu.number.NumberFormatter.SignDisplay; |
19 import com.ibm.icu.number.NumberFormatter.UnitWidth; | 19 import com.ibm.icu.number.NumberFormatter.UnitWidth; |
20 import com.ibm.icu.text.DecimalFormatSymbols; | 20 import com.ibm.icu.text.DecimalFormatSymbols; |
21 import com.ibm.icu.text.NumberFormat; | 21 import com.ibm.icu.text.NumberFormat; |
22 import com.ibm.icu.text.NumberingSystem; | 22 import com.ibm.icu.text.NumberingSystem; |
23 import com.ibm.icu.text.PluralRules; | 23 import com.ibm.icu.text.PluralRules; |
24 import com.ibm.icu.util.Currency; | 24 import com.ibm.icu.util.Currency; |
25 import com.ibm.icu.util.MeasureUnit; | 25 import com.ibm.icu.util.MeasureUnit; |
26 | 26 |
27 /** | 27 /** |
28 * This is the "brain" of the number formatting pipeline. It ties all the pieces
together, taking in a MacroProps and a | 28 * This is the "brain" of the number formatting pipeline. It ties all the pieces
together, taking in a |
29 * DecimalQuantity and outputting a properly formatted number string. | 29 * MacroProps and a DecimalQuantity and outputting a properly formatted number s
tring. |
30 * | 30 * |
31 * <p> | 31 * <p> |
32 * This class, as well as NumberPropertyMapper, could go into the impl package,
but they depend on too many | 32 * This class, as well as NumberPropertyMapper, could go into the impl package,
but they depend on too |
33 * package-private members of the public APIs. | 33 * many package-private members of the public APIs. |
34 */ | 34 */ |
35 class NumberFormatterImpl { | 35 class NumberFormatterImpl { |
36 | 36 |
37 /** Builds a "safe" MicroPropsGenerator, which is thread-safe and can be use
d repeatedly. */ | 37 /** Builds a "safe" MicroPropsGenerator, which is thread-safe and can be use
d repeatedly. */ |
38 public static NumberFormatterImpl fromMacros(MacroProps macros) { | 38 public static NumberFormatterImpl fromMacros(MacroProps macros) { |
39 MicroPropsGenerator microPropsGenerator = macrosToMicroGenerator(macros,
true); | 39 MicroPropsGenerator microPropsGenerator = macrosToMicroGenerator(macros,
true); |
40 return new NumberFormatterImpl(microPropsGenerator); | 40 return new NumberFormatterImpl(microPropsGenerator); |
41 } | 41 } |
42 | 42 |
43 /** Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper b
ut can be used only once. */ | 43 /** |
44 public static MicroProps applyStatic(MacroProps macros, DecimalQuantity inVa
lue, NumberStringBuilder outString) { | 44 * Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper bu
t can be used only once. |
| 45 */ |
| 46 public static MicroProps applyStatic( |
| 47 MacroProps macros, |
| 48 DecimalQuantity inValue, |
| 49 NumberStringBuilder outString) { |
45 MicroPropsGenerator microPropsGenerator = macrosToMicroGenerator(macros,
false); | 50 MicroPropsGenerator microPropsGenerator = macrosToMicroGenerator(macros,
false); |
46 MicroProps micros = microPropsGenerator.processQuantity(inValue); | 51 MicroProps micros = microPropsGenerator.processQuantity(inValue); |
47 microsToString(micros, inValue, outString); | 52 microsToString(micros, inValue, outString); |
48 return micros; | 53 return micros; |
49 } | 54 } |
50 | 55 |
51 private static final Currency DEFAULT_CURRENCY = Currency.getInstance("XXX")
; | 56 private static final Currency DEFAULT_CURRENCY = Currency.getInstance("XXX")
; |
52 | 57 |
53 final MicroPropsGenerator microPropsGenerator; | 58 final MicroPropsGenerator microPropsGenerator; |
54 | 59 |
(...skipping 22 matching lines...) Expand all Loading... |
77 | 82 |
78 private static boolean unitIsPercent(MeasureUnit unit) { | 83 private static boolean unitIsPercent(MeasureUnit unit) { |
79 return unit != null && "percent".equals(unit.getSubtype()); | 84 return unit != null && "percent".equals(unit.getSubtype()); |
80 } | 85 } |
81 | 86 |
82 private static boolean unitIsPermille(MeasureUnit unit) { | 87 private static boolean unitIsPermille(MeasureUnit unit) { |
83 return unit != null && "permille".equals(unit.getSubtype()); | 88 return unit != null && "permille".equals(unit.getSubtype()); |
84 } | 89 } |
85 | 90 |
86 /** | 91 /** |
87 * Synthesizes the MacroProps into a MicroPropsGenerator. All information, i
ncluding the locale, is encoded into the | 92 * Synthesizes the MacroProps into a MicroPropsGenerator. All information, i
ncluding the locale, is |
88 * MicroPropsGenerator, except for the quantity itself, which is left abstra
ct and must be provided to the returned | 93 * encoded into the MicroPropsGenerator, except for the quantity itself, whi
ch is left abstract and |
89 * MicroPropsGenerator instance. | 94 * must be provided to the returned MicroPropsGenerator instance. |
90 * | 95 * |
91 * @see MicroPropsGenerator | 96 * @see MicroPropsGenerator |
92 * @param macros | 97 * @param macros |
93 * The {@link MacroProps} to consume. This method does not mutate
the MacroProps instance. | 98 * The {@link MacroProps} to consume. This method does not mutate
the MacroProps instance. |
94 * @param safe | 99 * @param safe |
95 * If true, the returned MicroPropsGenerator will be thread-safe.
If false, the returned value will | 100 * If true, the returned MicroPropsGenerator will be thread-safe.
If false, the returned |
96 * <em>not</em> be thread-safe, intended for a single "one-shot"
use only. Building the thread-safe | 101 * value will <em>not</em> be thread-safe, intended for a single
"one-shot" use only. |
97 * object is more expensive. | 102 * Building the thread-safe object is more expensive. |
98 */ | 103 */ |
99 private static MicroPropsGenerator macrosToMicroGenerator(MacroProps macros,
boolean safe) { | 104 private static MicroPropsGenerator macrosToMicroGenerator(MacroProps macros,
boolean safe) { |
100 MicroProps micros = new MicroProps(safe); | 105 MicroProps micros = new MicroProps(safe); |
101 MicroPropsGenerator chain = micros; | 106 MicroPropsGenerator chain = micros; |
102 | 107 |
103 // TODO: Normalize the currency (accept symbols from DecimalFormatSymbol
s)? | 108 // TODO: Normalize the currency (accept symbols from DecimalFormatSymbol
s)? |
104 // currency = CustomSymbolCurrency.resolve(currency, input.loc, micros.s
ymbols); | 109 // currency = CustomSymbolCurrency.resolve(currency, input.loc, micros.s
ymbols); |
105 | 110 |
106 // Pre-compute a few values for efficiency. | 111 // Pre-compute a few values for efficiency. |
107 boolean isCurrency = unitIsCurrency(macros.unit); | 112 boolean isCurrency = unitIsCurrency(macros.unit); |
108 boolean isNoUnit = unitIsNoUnit(macros.unit); | 113 boolean isNoUnit = unitIsNoUnit(macros.unit); |
109 boolean isPercent = isNoUnit && unitIsPercent(macros.unit); | 114 boolean isPercent = isNoUnit && unitIsPercent(macros.unit); |
110 boolean isPermille = isNoUnit && unitIsPermille(macros.unit); | 115 boolean isPermille = isNoUnit && unitIsPermille(macros.unit); |
111 boolean isCldrUnit = !isCurrency && !isNoUnit; | 116 boolean isCldrUnit = !isCurrency && !isNoUnit; |
112 boolean isAccounting = macros.sign == SignDisplay.ACCOUNTING || macros.s
ign == SignDisplay.ACCOUNTING_ALWAYS; | 117 boolean isAccounting = macros.sign == SignDisplay.ACCOUNTING |
| 118 || macros.sign == SignDisplay.ACCOUNTING_ALWAYS; |
113 Currency currency = isCurrency ? (Currency) macros.unit : DEFAULT_CURREN
CY; | 119 Currency currency = isCurrency ? (Currency) macros.unit : DEFAULT_CURREN
CY; |
114 UnitWidth unitWidth = UnitWidth.SHORT; | 120 UnitWidth unitWidth = UnitWidth.SHORT; |
115 if (macros.unitWidth != null) { | 121 if (macros.unitWidth != null) { |
116 unitWidth = macros.unitWidth; | 122 unitWidth = macros.unitWidth; |
117 } | 123 } |
118 PluralRules rules = macros.rules; | 124 PluralRules rules = macros.rules; |
119 | 125 |
120 // Select the numbering system. | 126 // Select the numbering system. |
121 NumberingSystem ns; | 127 NumberingSystem ns; |
122 if (macros.symbols instanceof NumberingSystem) { | 128 if (macros.symbols instanceof NumberingSystem) { |
123 ns = (NumberingSystem) macros.symbols; | 129 ns = (NumberingSystem) macros.symbols; |
124 } else { | 130 } else { |
125 // TODO: Is there a way to avoid creating the NumberingSystem object
? | 131 // TODO: Is there a way to avoid creating the NumberingSystem object
? |
126 ns = NumberingSystem.getInstance(macros.loc); | 132 ns = NumberingSystem.getInstance(macros.loc); |
127 } | 133 } |
128 String nsName = ns.getName(); | 134 String nsName = ns.getName(); |
129 | 135 |
130 // Load and parse the pattern string. It is used for grouping sizes and
affixes only. | 136 // Load and parse the pattern string. It is used for grouping sizes and
affixes only. |
131 int patternStyle; | 137 int patternStyle; |
132 if (isPercent || isPermille) { | 138 if (isPercent || isPermille) { |
133 patternStyle = NumberFormat.PERCENTSTYLE; | 139 patternStyle = NumberFormat.PERCENTSTYLE; |
134 } else if (!isCurrency || unitWidth == UnitWidth.FULL_NAME) { | 140 } else if (!isCurrency || unitWidth == UnitWidth.FULL_NAME) { |
135 patternStyle = NumberFormat.NUMBERSTYLE; | 141 patternStyle = NumberFormat.NUMBERSTYLE; |
136 } else if (isAccounting) { | 142 } else if (isAccounting) { |
137 // NOTE: Although ACCOUNTING and ACCOUNTING_ALWAYS are only supporte
d in currencies right now, | 143 // NOTE: Although ACCOUNTING and ACCOUNTING_ALWAYS are only supporte
d in currencies right |
| 144 // now, |
138 // the API contract allows us to add support to other units in the f
uture. | 145 // the API contract allows us to add support to other units in the f
uture. |
139 patternStyle = NumberFormat.ACCOUNTINGCURRENCYSTYLE; | 146 patternStyle = NumberFormat.ACCOUNTINGCURRENCYSTYLE; |
140 } else { | 147 } else { |
141 patternStyle = NumberFormat.CURRENCYSTYLE; | 148 patternStyle = NumberFormat.CURRENCYSTYLE; |
142 } | 149 } |
143 String pattern = NumberFormat.getPatternForStyleAndNumberingSystem(macro
s.loc, nsName, patternStyle); | 150 String pattern = NumberFormat |
| 151 .getPatternForStyleAndNumberingSystem(macros.loc, nsName, patter
nStyle); |
144 ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(p
attern); | 152 ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(p
attern); |
145 | 153 |
146 ////////////////////////////////////////////////////////////////////////
///////////// | 154 ////////////////////////////////////////////////////////////////////////
///////////// |
147 /// START POPULATING THE DEFAULT MICROPROPS AND BUILDING THE MICROPROPS
GENERATOR /// | 155 /// START POPULATING THE DEFAULT MICROPROPS AND BUILDING THE MICROPROPS
GENERATOR /// |
148 ////////////////////////////////////////////////////////////////////////
///////////// | 156 ////////////////////////////////////////////////////////////////////////
///////////// |
149 | 157 |
150 // Symbols | 158 // Symbols |
151 if (macros.symbols instanceof DecimalFormatSymbols) { | 159 if (macros.symbols instanceof DecimalFormatSymbols) { |
152 micros.symbols = (DecimalFormatSymbols) macros.symbols; | 160 micros.symbols = (DecimalFormatSymbols) macros.symbols; |
153 } else { | 161 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 } else { | 248 } else { |
241 chain = patternMod.addToChain(chain); | 249 chain = patternMod.addToChain(chain); |
242 } | 250 } |
243 | 251 |
244 // Outer modifier (CLDR units and currency long names) | 252 // Outer modifier (CLDR units and currency long names) |
245 if (isCldrUnit) { | 253 if (isCldrUnit) { |
246 if (rules == null) { | 254 if (rules == null) { |
247 // Lazily create PluralRules | 255 // Lazily create PluralRules |
248 rules = PluralRules.forLocale(macros.loc); | 256 rules = PluralRules.forLocale(macros.loc); |
249 } | 257 } |
250 chain = LongNameHandler.forMeasureUnit(macros.loc, macros.unit, unit
Width, rules, chain); | 258 chain = LongNameHandler |
| 259 .forMeasureUnit(macros.loc, macros.unit, macros.perUnit, uni
tWidth, rules, chain); |
251 } else if (isCurrency && unitWidth == UnitWidth.FULL_NAME) { | 260 } else if (isCurrency && unitWidth == UnitWidth.FULL_NAME) { |
252 if (rules == null) { | 261 if (rules == null) { |
253 // Lazily create PluralRules | 262 // Lazily create PluralRules |
254 rules = PluralRules.forLocale(macros.loc); | 263 rules = PluralRules.forLocale(macros.loc); |
255 } | 264 } |
256 chain = LongNameHandler.forCurrencyLongNames(macros.loc, currency, r
ules, chain); | 265 chain = LongNameHandler.forCurrencyLongNames(macros.loc, currency, r
ules, chain); |
257 } else { | 266 } else { |
258 // No outer modifier required | 267 // No outer modifier required |
259 micros.modOuter = ConstantAffixModifier.EMPTY; | 268 micros.modOuter = ConstantAffixModifier.EMPTY; |
260 } | 269 } |
261 | 270 |
262 // Compact notation | 271 // Compact notation |
263 // NOTE: Compact notation can (but might not) override the middle modifi
er and rounding. | 272 // NOTE: Compact notation can (but might not) override the middle modifi
er and rounding. |
264 // It therefore needs to go at the end of the chain. | 273 // It therefore needs to go at the end of the chain. |
265 if (macros.notation instanceof CompactNotation) { | 274 if (macros.notation instanceof CompactNotation) { |
266 if (rules == null) { | 275 if (rules == null) { |
267 // Lazily create PluralRules | 276 // Lazily create PluralRules |
268 rules = PluralRules.forLocale(macros.loc); | 277 rules = PluralRules.forLocale(macros.loc); |
269 } | 278 } |
270 CompactType compactType = (macros.unit instanceof Currency && macros
.unitWidth != UnitWidth.FULL_NAME) | 279 CompactType compactType = (macros.unit instanceof Currency |
271 ? CompactType.CURRENCY | 280 && macros.unitWidth != UnitWidth.FULL_NAME) ? CompactType.CU
RRENCY |
272 : CompactType.DECIMAL; | 281 : CompactType.DECIMAL; |
273 chain = ((CompactNotation) macros.notation).withLocaleData(macros.lo
c, nsName, compactType, rules, | 282 chain = ((CompactNotation) macros.notation).withLocaleData(macros.lo
c, |
274 safe ? patternMod : null, chain); | 283 nsName, |
| 284 compactType, |
| 285 rules, |
| 286 safe ? patternMod : null, |
| 287 chain); |
275 } | 288 } |
276 | 289 |
277 return chain; | 290 return chain; |
278 } | 291 } |
279 | 292 |
280 ////////// | 293 ////////// |
281 | 294 |
282 /** | 295 /** |
283 * Synthesizes the output string from a MicroProps and DecimalQuantity. | 296 * Synthesizes the output string from a MicroProps and DecimalQuantity. |
284 * | 297 * |
285 * @param micros | 298 * @param micros |
286 * The MicroProps after the quantity has been consumed. Will not
be mutated. | 299 * The MicroProps after the quantity has been consumed. Will not
be mutated. |
287 * @param quantity | 300 * @param quantity |
288 * The DecimalQuantity to be rendered. May be mutated. | 301 * The DecimalQuantity to be rendered. May be mutated. |
289 * @param string | 302 * @param string |
290 * The output string. Will be mutated. | 303 * The output string. Will be mutated. |
291 */ | 304 */ |
292 private static void microsToString(MicroProps micros, DecimalQuantity quanti
ty, NumberStringBuilder string) { | 305 private static void microsToString( |
| 306 MicroProps micros, |
| 307 DecimalQuantity quantity, |
| 308 NumberStringBuilder string) { |
293 micros.rounding.apply(quantity); | 309 micros.rounding.apply(quantity); |
294 if (micros.integerWidth.maxInt == -1) { | 310 if (micros.integerWidth.maxInt == -1) { |
295 quantity.setIntegerLength(micros.integerWidth.minInt, Integer.MAX_VA
LUE); | 311 quantity.setIntegerLength(micros.integerWidth.minInt, Integer.MAX_VA
LUE); |
296 } else { | 312 } else { |
297 quantity.setIntegerLength(micros.integerWidth.minInt, micros.integer
Width.maxInt); | 313 quantity.setIntegerLength(micros.integerWidth.minInt, micros.integer
Width.maxInt); |
298 } | 314 } |
299 int length = writeNumber(micros, quantity, string); | 315 int length = writeNumber(micros, quantity, string); |
300 // NOTE: When range formatting is added, these modifiers can bubble up. | 316 // NOTE: When range formatting is added, these modifiers can bubble up. |
301 // For now, apply them all here at once. | 317 // For now, apply them all here at once. |
302 // Always apply the inner modifier (which is "strong"). | 318 // Always apply the inner modifier (which is "strong"). |
303 length += micros.modInner.apply(string, 0, length); | 319 length += micros.modInner.apply(string, 0, length); |
304 if (micros.padding.isValid()) { | 320 if (micros.padding.isValid()) { |
305 micros.padding.padAndApply(micros.modMiddle, micros.modOuter, string
, 0, length); | 321 micros.padding.padAndApply(micros.modMiddle, micros.modOuter, string
, 0, length); |
306 } else { | 322 } else { |
307 length += micros.modMiddle.apply(string, 0, length); | 323 length += micros.modMiddle.apply(string, 0, length); |
308 length += micros.modOuter.apply(string, 0, length); | 324 length += micros.modOuter.apply(string, 0, length); |
309 } | 325 } |
310 } | 326 } |
311 | 327 |
312 private static int writeNumber(MicroProps micros, DecimalQuantity quantity,
NumberStringBuilder string) { | 328 private static int writeNumber( |
| 329 MicroProps micros, |
| 330 DecimalQuantity quantity, |
| 331 NumberStringBuilder string) { |
313 int length = 0; | 332 int length = 0; |
314 if (quantity.isInfinite()) { | 333 if (quantity.isInfinite()) { |
315 length += string.insert(length, micros.symbols.getInfinity(), Number
Format.Field.INTEGER); | 334 length += string.insert(length, micros.symbols.getInfinity(), Number
Format.Field.INTEGER); |
316 | 335 |
317 } else if (quantity.isNaN()) { | 336 } else if (quantity.isNaN()) { |
318 length += string.insert(length, micros.symbols.getNaN(), NumberForma
t.Field.INTEGER); | 337 length += string.insert(length, micros.symbols.getNaN(), NumberForma
t.Field.INTEGER); |
319 | 338 |
320 } else { | 339 } else { |
321 // Add the integer digits | 340 // Add the integer digits |
322 length += writeIntegerDigits(micros, quantity, string); | 341 length += writeIntegerDigits(micros, quantity, string); |
323 | 342 |
324 // Add the decimal point | 343 // Add the decimal point |
325 if (quantity.getLowerDisplayMagnitude() < 0 || micros.decimal == Dec
imalSeparatorDisplay.ALWAYS) { | 344 if (quantity.getLowerDisplayMagnitude() < 0 |
326 length += string.insert(length, micros.useCurrency ? micros.symb
ols.getMonetaryDecimalSeparatorString() | 345 || micros.decimal == DecimalSeparatorDisplay.ALWAYS) { |
327 : micros.symbols.getDecimalSeparatorString(), NumberForm
at.Field.DECIMAL_SEPARATOR); | 346 length += string.insert(length, |
| 347 micros.useCurrency ? micros.symbols.getMonetaryDecimalSe
paratorString() |
| 348 : micros.symbols.getDecimalSeparatorString(), |
| 349 NumberFormat.Field.DECIMAL_SEPARATOR); |
328 } | 350 } |
329 | 351 |
330 // Add the fraction digits | 352 // Add the fraction digits |
331 length += writeFractionDigits(micros, quantity, string); | 353 length += writeFractionDigits(micros, quantity, string); |
332 } | 354 } |
333 | 355 |
334 return length; | 356 return length; |
335 } | 357 } |
336 | 358 |
337 private static int writeIntegerDigits(MicroProps micros, DecimalQuantity qua
ntity, NumberStringBuilder string) { | 359 private static int writeIntegerDigits( |
| 360 MicroProps micros, |
| 361 DecimalQuantity quantity, |
| 362 NumberStringBuilder string) { |
338 int length = 0; | 363 int length = 0; |
339 int integerCount = quantity.getUpperDisplayMagnitude() + 1; | 364 int integerCount = quantity.getUpperDisplayMagnitude() + 1; |
340 for (int i = 0; i < integerCount; i++) { | 365 for (int i = 0; i < integerCount; i++) { |
341 // Add grouping separator | 366 // Add grouping separator |
342 if (micros.grouping.groupAtPosition(i, quantity)) { | 367 if (micros.grouping.groupAtPosition(i, quantity)) { |
343 length += string.insert(0, micros.useCurrency ? micros.symbols.g
etMonetaryGroupingSeparatorString() | 368 length += string.insert(0, |
344 : micros.symbols.getGroupingSeparatorString(), NumberFor
mat.Field.GROUPING_SEPARATOR); | 369 micros.useCurrency ? micros.symbols.getMonetaryGroupingS
eparatorString() |
| 370 : micros.symbols.getGroupingSeparatorString(), |
| 371 NumberFormat.Field.GROUPING_SEPARATOR); |
345 } | 372 } |
346 | 373 |
347 // Get and append the next digit value | 374 // Get and append the next digit value |
348 byte nextDigit = quantity.getDigit(i); | 375 byte nextDigit = quantity.getDigit(i); |
349 if (micros.symbols.getCodePointZero() != -1) { | 376 if (micros.symbols.getCodePointZero() != -1) { |
350 length += string.insertCodePoint(0, micros.symbols.getCodePointZ
ero() + nextDigit, | 377 length += string.insertCodePoint(0, |
| 378 micros.symbols.getCodePointZero() + nextDigit, |
351 NumberFormat.Field.INTEGER); | 379 NumberFormat.Field.INTEGER); |
352 } else { | 380 } else { |
353 length += string.insert(0, micros.symbols.getDigitStringsLocal()
[nextDigit], | 381 length += string.insert(0, |
| 382 micros.symbols.getDigitStringsLocal()[nextDigit], |
354 NumberFormat.Field.INTEGER); | 383 NumberFormat.Field.INTEGER); |
355 } | 384 } |
356 } | 385 } |
357 return length; | 386 return length; |
358 } | 387 } |
359 | 388 |
360 private static int writeFractionDigits(MicroProps micros, DecimalQuantity qu
antity, NumberStringBuilder string) { | 389 private static int writeFractionDigits( |
| 390 MicroProps micros, |
| 391 DecimalQuantity quantity, |
| 392 NumberStringBuilder string) { |
361 int length = 0; | 393 int length = 0; |
362 int fractionCount = -quantity.getLowerDisplayMagnitude(); | 394 int fractionCount = -quantity.getLowerDisplayMagnitude(); |
363 for (int i = 0; i < fractionCount; i++) { | 395 for (int i = 0; i < fractionCount; i++) { |
364 // Get and append the next digit value | 396 // Get and append the next digit value |
365 byte nextDigit = quantity.getDigit(-i - 1); | 397 byte nextDigit = quantity.getDigit(-i - 1); |
366 if (micros.symbols.getCodePointZero() != -1) { | 398 if (micros.symbols.getCodePointZero() != -1) { |
367 length += string.appendCodePoint(micros.symbols.getCodePointZero
() + nextDigit, | 399 length += string.appendCodePoint(micros.symbols.getCodePointZero
() + nextDigit, |
368 NumberFormat.Field.FRACTION); | 400 NumberFormat.Field.FRACTION); |
369 } else { | 401 } else { |
370 length += string.append(micros.symbols.getDigitStringsLocal()[ne
xtDigit], NumberFormat.Field.FRACTION); | 402 length += string.append(micros.symbols.getDigitStringsLocal()[ne
xtDigit], |
| 403 NumberFormat.Field.FRACTION); |
371 } | 404 } |
372 } | 405 } |
373 return length; | 406 return length; |
374 } | 407 } |
375 } | 408 } |
LEFT | RIGHT |