| /* 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.impl.number; |
| |
| import android.icu.impl.ICUData; |
| import android.icu.impl.ICUResourceBundle; |
| import android.icu.impl.number.PatternStringParser.ParsedPatternInfo; |
| import android.icu.number.NumberFormatter.GroupingStrategy; |
| import android.icu.util.ULocale; |
| import android.icu.util.UResourceBundle; |
| |
| /** |
| * A full options object for grouping sizes. |
| * @hide Only a subset of ICU is exposed in Android |
| */ |
| public class Grouper { |
| |
| private static final Grouper GROUPER_NEVER = new Grouper((short) -1, (short) -1, (short) -2); |
| private static final Grouper GROUPER_MIN2 = new Grouper((short) -2, (short) -2, (short) -3); |
| private static final Grouper GROUPER_AUTO = new Grouper((short) -2, (short) -2, (short) -2); |
| private static final Grouper GROUPER_ON_ALIGNED = new Grouper((short) -4, (short) -4, (short) 1); |
| |
| private static final Grouper GROUPER_WESTERN = new Grouper((short) 3, (short) 3, (short) 1); |
| private static final Grouper GROUPER_INDIC = new Grouper((short) 3, (short) 2, (short) 1); |
| private static final Grouper GROUPER_WESTERN_MIN2 = new Grouper((short) 3, (short) 3, (short) 2); |
| private static final Grouper GROUPER_INDIC_MIN2 = new Grouper((short) 3, (short) 2, (short) 2); |
| |
| /** |
| * Convert from the GroupingStrategy enum to a Grouper object. |
| */ |
| public static Grouper forStrategy(GroupingStrategy grouping) { |
| switch (grouping) { |
| case OFF: |
| return GROUPER_NEVER; |
| case MIN2: |
| return GROUPER_MIN2; |
| case AUTO: |
| return GROUPER_AUTO; |
| case ON_ALIGNED: |
| return GROUPER_ON_ALIGNED; |
| case THOUSANDS: |
| return GROUPER_WESTERN; |
| default: |
| throw new AssertionError(); |
| } |
| } |
| |
| /** |
| * Resolve the values in Properties to a Grouper object. |
| */ |
| public static Grouper forProperties(DecimalFormatProperties properties) { |
| if (!properties.getGroupingUsed()) { |
| return GROUPER_NEVER; |
| } |
| short grouping1 = (short) properties.getGroupingSize(); |
| short grouping2 = (short) properties.getSecondaryGroupingSize(); |
| short minGrouping = (short) properties.getMinimumGroupingDigits(); |
| grouping1 = grouping1 > 0 ? grouping1 : grouping2 > 0 ? grouping2 : grouping1; |
| grouping2 = grouping2 > 0 ? grouping2 : grouping1; |
| return getInstance(grouping1, grouping2, minGrouping); |
| } |
| |
| public static Grouper getInstance(short grouping1, short grouping2, short minGrouping) { |
| if (grouping1 == -1) { |
| return GROUPER_NEVER; |
| } else if (grouping1 == 3 && grouping2 == 3 && minGrouping == 1) { |
| return GROUPER_WESTERN; |
| } else if (grouping1 == 3 && grouping2 == 2 && minGrouping == 1) { |
| return GROUPER_INDIC; |
| } else if (grouping1 == 3 && grouping2 == 3 && minGrouping == 2) { |
| return GROUPER_WESTERN_MIN2; |
| } else if (grouping1 == 3 && grouping2 == 2 && minGrouping == 2) { |
| return GROUPER_INDIC_MIN2; |
| } else { |
| return new Grouper(grouping1, grouping2, minGrouping); |
| } |
| } |
| |
| private static short getMinGroupingForLocale(ULocale locale) { |
| // TODO: Cache this? |
| ICUResourceBundle resource = (ICUResourceBundle) UResourceBundle |
| .getBundleInstance(ICUData.ICU_BASE_NAME, locale); |
| String result = resource.getStringWithFallback("NumberElements/minimumGroupingDigits"); |
| return Short.parseShort(result); |
| } |
| |
| /** |
| * The primary grouping size, with the following special values: |
| * <ul> |
| * <li>-1 = no grouping |
| * <li>-2 = needs locale data |
| * <li>-4 = fall back to Western grouping if not in locale |
| * </ul> |
| */ |
| private final short grouping1; |
| |
| /** |
| * The secondary grouping size, with the following special values: |
| * <ul> |
| * <li>-1 = no grouping |
| * <li>-2 = needs locale data |
| * <li>-4 = fall back to Western grouping if not in locale |
| * </ul> |
| */ |
| private final short grouping2; |
| |
| /** |
| * The minimum grouping size, with the following special values: |
| * <ul> |
| * <li>-2 = needs locale data |
| * <li>-3 = no less than 2 |
| * </ul> |
| */ |
| private final short minGrouping; |
| |
| private Grouper(short grouping1, short grouping2, short minGrouping) { |
| this.grouping1 = grouping1; |
| this.grouping2 = grouping2; |
| this.minGrouping = minGrouping; |
| } |
| |
| public Grouper withLocaleData(ULocale locale, ParsedPatternInfo patternInfo) { |
| short minGrouping; |
| if (this.minGrouping == -2) { |
| minGrouping = getMinGroupingForLocale(locale); |
| } else if (this.minGrouping == -3) { |
| minGrouping = (short) Math.max(2, getMinGroupingForLocale(locale)); |
| } else { |
| minGrouping = this.minGrouping; |
| } |
| |
| if (this.grouping1 != -2 && this.grouping2 != -4) { |
| if (minGrouping == this.minGrouping) { |
| return this; |
| } |
| return getInstance(this.grouping1, this.grouping2, minGrouping); |
| } |
| |
| short grouping1 = (short) (patternInfo.positive.groupingSizes & 0xffff); |
| short grouping2 = (short) ((patternInfo.positive.groupingSizes >>> 16) & 0xffff); |
| short grouping3 = (short) ((patternInfo.positive.groupingSizes >>> 32) & 0xffff); |
| if (grouping2 == -1) { |
| grouping1 = this.grouping1 == -4 ? (short) 3 : (short) -1; |
| } |
| if (grouping3 == -1) { |
| grouping2 = grouping1; |
| } |
| |
| return getInstance(grouping1, grouping2, minGrouping); |
| } |
| |
| public boolean groupAtPosition(int position, DecimalQuantity value) { |
| assert grouping1 != -2 && grouping1 != -4; |
| if (grouping1 == -1 || grouping1 == 0) { |
| // Either -1 or 0 means "no grouping" |
| return false; |
| } |
| position -= grouping1; |
| return position >= 0 |
| && (position % grouping2) == 0 |
| && value.getUpperDisplayMagnitude() - grouping1 + 1 >= minGrouping; |
| } |
| |
| public short getPrimary() { |
| return grouping1; |
| } |
| |
| public short getSecondary() { |
| return grouping2; |
| } |
| } |