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