• 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.parse;
5 
6 import java.util.Comparator;
7 
8 import ohos.global.icu.impl.StringSegment;
9 import ohos.global.icu.impl.number.DecimalQuantity_DualStorageBCD;
10 
11 /**
12  * Struct-like class to hold the results of a parsing routine.
13  *
14  * @author sffc
15  * @hide exposed on OHOS
16  */
17 public class ParsedNumber {
18 
19     /**
20      * The numerical value that was parsed.
21      */
22     public DecimalQuantity_DualStorageBCD quantity;
23 
24     /**
25      * The index of the last char consumed during parsing. If parsing started at index 0, this is equal
26      * to the number of chars consumed. This is NOT necessarily the same as the StringSegment offset;
27      * "weak" chars, like whitespace, change the offset, but the charsConsumed is not touched until a
28      * "strong" char is encountered.
29      */
30     public int charEnd;
31 
32     /**
33      * Boolean flags (see constants below).
34      */
35     public int flags;
36 
37     /**
38      * The pattern string corresponding to the prefix that got consumed.
39      */
40     public String prefix;
41 
42     /**
43      * The pattern string corresponding to the suffix that got consumed.
44      */
45     public String suffix;
46 
47     /**
48      * The currency that got consumed.
49      */
50     public String currencyCode;
51 
52     public static final int FLAG_NEGATIVE = 0x0001;
53     public static final int FLAG_PERCENT = 0x0002;
54     public static final int FLAG_PERMILLE = 0x0004;
55     public static final int FLAG_HAS_EXPONENT = 0x0008;
56     // public static final int FLAG_HAS_DEFAULT_CURRENCY = 0x0010; // no longer used
57     public static final int FLAG_HAS_DECIMAL_SEPARATOR = 0x0020;
58     public static final int FLAG_NAN = 0x0040;
59     public static final int FLAG_INFINITY = 0x0080;
60     public static final int FLAG_FAIL = 0x0100;
61 
62     /** A Comparator that favors ParsedNumbers with the most chars consumed. */
63     public static final Comparator<ParsedNumber> COMPARATOR = new Comparator<ParsedNumber>() {
64         @Override
65         public int compare(ParsedNumber o1, ParsedNumber o2) {
66             return o1.charEnd - o2.charEnd;
67         }
68     };
69 
ParsedNumber()70     public ParsedNumber() {
71         clear();
72     }
73 
74     /**
75      * Clears the data from this ParsedNumber, in effect failing the current parse.
76      */
clear()77     public void clear() {
78         quantity = null;
79         charEnd = 0;
80         flags = 0;
81         prefix = null;
82         suffix = null;
83         currencyCode = null;
84     }
85 
copyFrom(ParsedNumber other)86     public void copyFrom(ParsedNumber other) {
87         quantity = other.quantity == null ? null
88                 : (DecimalQuantity_DualStorageBCD) other.quantity.createCopy();
89         charEnd = other.charEnd;
90         flags = other.flags;
91         prefix = other.prefix;
92         suffix = other.suffix;
93         currencyCode = other.currencyCode;
94     }
95 
96     /**
97      * Call this method to register that a "strong" char was consumed. This should be done after calling
98      * {@link StringSegment#setOffset} or {@link StringSegment#adjustOffset} except when the char is
99      * "weak", like whitespace.
100      *
101      * <p>
102      * <strong>What is a strong versus weak char?</strong> The behavior of number parsing is to "stop"
103      * after reading the number, even if there is other content following the number. For example, after
104      * parsing the string "123 " (123 followed by a space), the cursor should be set to 3, not 4, even
105      * though there are matchers that accept whitespace. In this example, the digits are strong, whereas
106      * the whitespace is weak. Grouping separators are weak, whereas decimal separators are strong. Most
107      * other chars are strong.
108      *
109      * @param segment
110      *            The current StringSegment, usually immediately following a call to setOffset.
111      */
setCharsConsumed(StringSegment segment)112     public void setCharsConsumed(StringSegment segment) {
113         charEnd = segment.getOffset();
114     }
115 
116     /** Apply certain number-related flags to the DecimalQuantity. */
postProcess()117     public void postProcess() {
118         if (quantity != null && 0 != (flags & FLAG_NEGATIVE)) {
119             quantity.negate();
120         }
121     }
122 
123     /**
124      * Returns whether this the parse was successful. To be successful, at least one char must have been
125      * consumed, and the failure flag must not be set.
126      */
success()127     public boolean success() {
128         return charEnd > 0 && 0 == (flags & FLAG_FAIL);
129     }
130 
seenNumber()131     public boolean seenNumber() {
132         return quantity != null || 0 != (flags & FLAG_NAN) || 0 != (flags & FLAG_INFINITY);
133     }
134 
getNumber()135     public Number getNumber() {
136         return getNumber(0);
137     }
138 
139     /** @param parseFlags Configuration settings from ParsingUtils.java */
getNumber(int parseFlags)140     public Number getNumber(int parseFlags) {
141         boolean sawNaN = 0 != (flags & FLAG_NAN);
142         boolean sawInfinity = 0 != (flags & FLAG_INFINITY);
143         boolean forceBigDecimal = 0 != (parseFlags & ParsingUtils.PARSE_FLAG_FORCE_BIG_DECIMAL);
144         boolean integerOnly = 0 != (parseFlags & ParsingUtils.PARSE_FLAG_INTEGER_ONLY);
145 
146         // Check for NaN, infinity, and -0.0
147         if (sawNaN) {
148             return Double.NaN;
149         }
150         if (sawInfinity) {
151             if (0 != (flags & FLAG_NEGATIVE)) {
152                 return Double.NEGATIVE_INFINITY;
153             } else {
154                 return Double.POSITIVE_INFINITY;
155             }
156         }
157         assert quantity != null;
158         if (quantity.isZeroish() && quantity.isNegative() && !integerOnly) {
159             return -0.0;
160         }
161 
162         if (quantity.fitsInLong() && !forceBigDecimal) {
163             return quantity.toLong(false);
164         } else {
165             return quantity.toBigDecimal();
166         }
167 
168     }
169 
isBetterThan(ParsedNumber other)170     boolean isBetterThan(ParsedNumber other) {
171         return COMPARATOR.compare(this, other) > 0;
172     }
173 }
174