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.impl.number; 5 6 import ohos.global.icu.impl.ICUData; 7 import ohos.global.icu.impl.ICUResourceBundle; 8 import ohos.global.icu.impl.number.PatternStringParser.ParsedPatternInfo; 9 import ohos.global.icu.number.NumberFormatter.GroupingStrategy; 10 import ohos.global.icu.util.ULocale; 11 import ohos.global.icu.util.UResourceBundle; 12 13 /** 14 * A full options object for grouping sizes. 15 * @hide exposed on OHOS 16 */ 17 public class Grouper { 18 19 private static final Grouper GROUPER_NEVER = new Grouper((short) -1, (short) -1, (short) -2); 20 private static final Grouper GROUPER_MIN2 = new Grouper((short) -2, (short) -2, (short) -3); 21 private static final Grouper GROUPER_AUTO = new Grouper((short) -2, (short) -2, (short) -2); 22 private static final Grouper GROUPER_ON_ALIGNED = new Grouper((short) -4, (short) -4, (short) 1); 23 24 private static final Grouper GROUPER_WESTERN = new Grouper((short) 3, (short) 3, (short) 1); 25 private static final Grouper GROUPER_INDIC = new Grouper((short) 3, (short) 2, (short) 1); 26 private static final Grouper GROUPER_WESTERN_MIN2 = new Grouper((short) 3, (short) 3, (short) 2); 27 private static final Grouper GROUPER_INDIC_MIN2 = new Grouper((short) 3, (short) 2, (short) 2); 28 29 /** 30 * Convert from the GroupingStrategy enum to a Grouper object. 31 */ forStrategy(GroupingStrategy grouping)32 public static Grouper forStrategy(GroupingStrategy grouping) { 33 switch (grouping) { 34 case OFF: 35 return GROUPER_NEVER; 36 case MIN2: 37 return GROUPER_MIN2; 38 case AUTO: 39 return GROUPER_AUTO; 40 case ON_ALIGNED: 41 return GROUPER_ON_ALIGNED; 42 case THOUSANDS: 43 return GROUPER_WESTERN; 44 default: 45 throw new AssertionError(); 46 } 47 } 48 49 /** 50 * Resolve the values in Properties to a Grouper object. 51 */ forProperties(DecimalFormatProperties properties)52 public static Grouper forProperties(DecimalFormatProperties properties) { 53 if (!properties.getGroupingUsed()) { 54 return GROUPER_NEVER; 55 } 56 short grouping1 = (short) properties.getGroupingSize(); 57 short grouping2 = (short) properties.getSecondaryGroupingSize(); 58 short minGrouping = (short) properties.getMinimumGroupingDigits(); 59 grouping1 = grouping1 > 0 ? grouping1 : grouping2 > 0 ? grouping2 : grouping1; 60 grouping2 = grouping2 > 0 ? grouping2 : grouping1; 61 return getInstance(grouping1, grouping2, minGrouping); 62 } 63 getInstance(short grouping1, short grouping2, short minGrouping)64 public static Grouper getInstance(short grouping1, short grouping2, short minGrouping) { 65 if (grouping1 == -1) { 66 return GROUPER_NEVER; 67 } else if (grouping1 == 3 && grouping2 == 3 && minGrouping == 1) { 68 return GROUPER_WESTERN; 69 } else if (grouping1 == 3 && grouping2 == 2 && minGrouping == 1) { 70 return GROUPER_INDIC; 71 } else if (grouping1 == 3 && grouping2 == 3 && minGrouping == 2) { 72 return GROUPER_WESTERN_MIN2; 73 } else if (grouping1 == 3 && grouping2 == 2 && minGrouping == 2) { 74 return GROUPER_INDIC_MIN2; 75 } else { 76 return new Grouper(grouping1, grouping2, minGrouping); 77 } 78 } 79 getMinGroupingForLocale(ULocale locale)80 private static short getMinGroupingForLocale(ULocale locale) { 81 // TODO: Cache this? 82 ICUResourceBundle resource = (ICUResourceBundle) UResourceBundle 83 .getBundleInstance(ICUData.ICU_BASE_NAME, locale); 84 String result = resource.getStringWithFallback("NumberElements/minimumGroupingDigits"); 85 return Short.valueOf(result); 86 } 87 88 /** 89 * The primary grouping size, with the following special values: 90 * <ul> 91 * <li>-1 = no grouping 92 * <li>-2 = needs locale data 93 * <li>-4 = fall back to Western grouping if not in locale 94 * </ul> 95 */ 96 private final short grouping1; 97 98 /** 99 * The secondary grouping size, with the following special values: 100 * <ul> 101 * <li>-1 = no grouping 102 * <li>-2 = needs locale data 103 * <li>-4 = fall back to Western grouping if not in locale 104 * </ul> 105 */ 106 private final short grouping2; 107 108 /** 109 * The minimum gropuing size, with the following special values: 110 * <ul> 111 * <li>-2 = needs locale data 112 * <li>-3 = no less than 2 113 * </ul> 114 */ 115 private final short minGrouping; 116 Grouper(short grouping1, short grouping2, short minGrouping)117 private Grouper(short grouping1, short grouping2, short minGrouping) { 118 this.grouping1 = grouping1; 119 this.grouping2 = grouping2; 120 this.minGrouping = minGrouping; 121 } 122 withLocaleData(ULocale locale, ParsedPatternInfo patternInfo)123 public Grouper withLocaleData(ULocale locale, ParsedPatternInfo patternInfo) { 124 if (this.grouping1 != -2 && this.grouping1 != -4) { 125 return this; 126 } 127 128 short grouping1 = (short) (patternInfo.positive.groupingSizes & 0xffff); 129 short grouping2 = (short) ((patternInfo.positive.groupingSizes >>> 16) & 0xffff); 130 short grouping3 = (short) ((patternInfo.positive.groupingSizes >>> 32) & 0xffff); 131 if (grouping2 == -1) { 132 grouping1 = this.grouping1 == -4 ? (short) 3 : (short) -1; 133 } 134 if (grouping3 == -1) { 135 grouping2 = grouping1; 136 } 137 138 short minGrouping; 139 if (this.minGrouping == -2) { 140 minGrouping = getMinGroupingForLocale(locale); 141 } else if (this.minGrouping == -3) { 142 minGrouping = (short) Math.max(2, getMinGroupingForLocale(locale)); 143 } else { 144 minGrouping = this.minGrouping; 145 } 146 147 return getInstance(grouping1, grouping2, minGrouping); 148 } 149 groupAtPosition(int position, DecimalQuantity value)150 public boolean groupAtPosition(int position, DecimalQuantity value) { 151 assert grouping1 != -2 && grouping1 != -4; 152 if (grouping1 == -1 || grouping1 == 0) { 153 // Either -1 or 0 means "no grouping" 154 return false; 155 } 156 position -= grouping1; 157 return position >= 0 158 && (position % grouping2) == 0 159 && value.getUpperDisplayMagnitude() - grouping1 + 1 >= minGrouping; 160 } 161 getPrimary()162 public short getPrimary() { 163 return grouping1; 164 } 165 getSecondary()166 public short getSecondary() { 167 return grouping2; 168 } 169 }