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.util.HashMap; 7 import java.util.HashSet; 8 import java.util.Map; 9 import java.util.Set; 10 11 import ohos.global.icu.impl.StandardPlural; 12 import ohos.global.icu.impl.number.CompactData; 13 import ohos.global.icu.impl.number.CompactData.CompactType; 14 import ohos.global.icu.impl.number.DecimalFormatProperties; 15 import ohos.global.icu.impl.number.DecimalQuantity; 16 import ohos.global.icu.impl.number.MicroProps; 17 import ohos.global.icu.impl.number.MicroPropsGenerator; 18 import ohos.global.icu.impl.number.MutablePatternModifier; 19 import ohos.global.icu.impl.number.MutablePatternModifier.ImmutablePatternModifier; 20 import ohos.global.icu.impl.number.PatternStringParser; 21 import ohos.global.icu.impl.number.PatternStringParser.ParsedPatternInfo; 22 import ohos.global.icu.text.CompactDecimalFormat.CompactStyle; 23 import ohos.global.icu.text.NumberFormat; 24 import ohos.global.icu.text.PluralRules; 25 import ohos.global.icu.util.ULocale; 26 27 /** 28 * A class that defines the scientific notation style to be used when formatting numbers in 29 * NumberFormatter. 30 * 31 * <p> 32 * This class exposes no public functionality. To create a CompactNotation, use one of the factory 33 * methods in {@link Notation}. 34 * 35 * @see NumberFormatter 36 * @hide exposed on OHOS 37 */ 38 public class CompactNotation extends Notation { 39 40 final CompactStyle compactStyle; 41 final Map<String, Map<String, String>> compactCustomData; 42 43 /** 44 * Create a compact notation with custom data. 45 * @deprecated This API is ICU internal only. 46 * @see DecimalFormatProperties#setCompactCustomData 47 * @hide draft / provisional / internal are hidden on OHOS 48 */ 49 @Deprecated forCustomData(Map<String, Map<String, String>> compactCustomData)50 public static CompactNotation forCustomData(Map<String, Map<String, String>> compactCustomData) { 51 return new CompactNotation(compactCustomData); 52 } 53 CompactNotation(CompactStyle compactStyle)54 /* package-private */ CompactNotation(CompactStyle compactStyle) { 55 compactCustomData = null; 56 this.compactStyle = compactStyle; 57 } 58 CompactNotation(Map<String, Map<String, String>> compactCustomData)59 /* package-private */ CompactNotation(Map<String, Map<String, String>> compactCustomData) { 60 compactStyle = null; 61 this.compactCustomData = compactCustomData; 62 } 63 withLocaleData( ULocale locale, String nsName, CompactType compactType, PluralRules rules, MutablePatternModifier buildReference, boolean safe, MicroPropsGenerator parent)64 /* package-private */ MicroPropsGenerator withLocaleData( 65 ULocale locale, 66 String nsName, 67 CompactType compactType, 68 PluralRules rules, 69 MutablePatternModifier buildReference, 70 boolean safe, 71 MicroPropsGenerator parent) { 72 // TODO: Add a data cache? It would be keyed by locale, nsName, compact type, and compact style. 73 return new CompactHandler(this, locale, nsName, compactType, rules, buildReference, safe, parent); 74 } 75 76 private static class CompactHandler implements MicroPropsGenerator { 77 78 final PluralRules rules; 79 final MicroPropsGenerator parent; 80 final Map<String, ImmutablePatternModifier> precomputedMods; 81 final MutablePatternModifier unsafePatternModifier; 82 final CompactData data; 83 CompactHandler( CompactNotation notation, ULocale locale, String nsName, CompactType compactType, PluralRules rules, MutablePatternModifier buildReference, boolean safe, MicroPropsGenerator parent)84 private CompactHandler( 85 CompactNotation notation, 86 ULocale locale, 87 String nsName, 88 CompactType compactType, 89 PluralRules rules, 90 MutablePatternModifier buildReference, 91 boolean safe, 92 MicroPropsGenerator parent) { 93 this.rules = rules; 94 this.parent = parent; 95 this.data = new CompactData(); 96 if (notation.compactStyle != null) { 97 data.populate(locale, nsName, notation.compactStyle, compactType); 98 } else { 99 data.populate(notation.compactCustomData); 100 } 101 if (safe) { 102 // Safe code path 103 precomputedMods = new HashMap<>(); 104 precomputeAllModifiers(buildReference); 105 unsafePatternModifier = null; 106 } else { 107 // Unsafe code path 108 precomputedMods = null; 109 unsafePatternModifier = buildReference; 110 } 111 } 112 113 /** Used by the safe code path */ precomputeAllModifiers(MutablePatternModifier buildReference)114 private void precomputeAllModifiers(MutablePatternModifier buildReference) { 115 Set<String> allPatterns = new HashSet<>(); 116 data.getUniquePatterns(allPatterns); 117 118 for (String patternString : allPatterns) { 119 ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString); 120 buildReference.setPatternInfo(patternInfo, NumberFormat.Field.COMPACT); 121 precomputedMods.put(patternString, buildReference.createImmutable()); 122 } 123 } 124 125 @Override processQuantity(DecimalQuantity quantity)126 public MicroProps processQuantity(DecimalQuantity quantity) { 127 MicroProps micros = parent.processQuantity(quantity); 128 assert micros.rounder != null; 129 130 // Treat zero, NaN, and infinity as if they had magnitude 0 131 int magnitude; 132 int multiplier = 0; 133 if (quantity.isZeroish()) { 134 magnitude = 0; 135 micros.rounder.apply(quantity); 136 } else { 137 multiplier = micros.rounder.chooseMultiplierAndApply(quantity, data); 138 magnitude = quantity.isZeroish() ? 0 : quantity.getMagnitude(); 139 magnitude -= multiplier; 140 } 141 142 StandardPlural plural = quantity.getStandardPlural(rules); 143 String patternString = data.getPattern(magnitude, plural); 144 if (patternString == null) { 145 // Use the default (non-compact) modifier. 146 // No need to take any action. 147 } else if (precomputedMods != null) { 148 // Safe code path. 149 // Java uses a hash set here for O(1) lookup. C++ uses a linear search. 150 ImmutablePatternModifier mod = precomputedMods.get(patternString); 151 mod.applyToMicros(micros, quantity); 152 } else { 153 // Unsafe code path. 154 // Overwrite the PatternInfo in the existing modMiddle. 155 ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString); 156 unsafePatternModifier.setPatternInfo(patternInfo, NumberFormat.Field.COMPACT); 157 unsafePatternModifier.setNumberProperties(quantity.signum(), null); 158 micros.modMiddle = unsafePatternModifier; 159 } 160 161 // Change the exponent only after we select appropriate plural form 162 // for formatting purposes so that we preserve expected formatted 163 // string behavior. 164 quantity.adjustExponent(-1 * multiplier); 165 166 // We already performed rounding. Do not perform it again. 167 micros.rounder = null; 168 169 return micros; 170 } 171 } 172 }