• 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.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 }