blob: 49e675ef90f53b09106d98cf5b4b215470e2e8f0 [file] [log] [blame]
/* GENERATED SOURCE. DO NOT MODIFY. */
// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
package android.icu.impl.number.parse;
import android.icu.impl.StringSegment;
import android.icu.impl.number.Grouper;
import android.icu.text.DecimalFormatSymbols;
import android.icu.text.UnicodeSet;
/**
* @author sffc
* @hide Only a subset of ICU is exposed in Android
*
*/
public class ScientificMatcher implements NumberParseMatcher {
private final String exponentSeparatorString;
private final DecimalMatcher exponentMatcher;
public static ScientificMatcher getInstance(DecimalFormatSymbols symbols, Grouper grouper) {
// TODO: Static-initialize most common instances?
return new ScientificMatcher(symbols, grouper);
}
private ScientificMatcher(DecimalFormatSymbols symbols, Grouper grouper) {
exponentSeparatorString = symbols.getExponentSeparator();
exponentMatcher = DecimalMatcher.getInstance(symbols,
grouper,
ParsingUtils.PARSE_FLAG_DECIMAL_SCIENTIFIC | ParsingUtils.PARSE_FLAG_INTEGER_ONLY);
}
@Override
public boolean match(StringSegment segment, ParsedNumber result) {
// Only accept scientific notation after the mantissa.
if (!result.seenNumber()) {
return false;
}
// First match the scientific separator, and then match another number after it.
int overlap1 = segment.getCommonPrefixLength(exponentSeparatorString);
if (overlap1 == exponentSeparatorString.length()) {
// Full exponent separator match.
// First attempt to get a code point, returning true if we can't get one.
segment.adjustOffset(overlap1);
if (segment.length() == 0) {
return true;
}
// Allow a sign, and then try to match digits.
boolean minusSign = false;
if (segment.startsWith(UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.MINUS_SIGN))) {
minusSign = true;
segment.adjustOffsetByCodePoint();
} else if (segment.startsWith(UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.PLUS_SIGN))) {
segment.adjustOffsetByCodePoint();
}
int digitsOffset = segment.getOffset();
boolean digitsReturnValue = exponentMatcher.match(segment, result, minusSign);
if (segment.getOffset() != digitsOffset) {
// At least one exponent digit was matched.
result.flags |= ParsedNumber.FLAG_HAS_EXPONENT;
} else {
// No exponent digits were matched; un-match the exponent separator.
segment.adjustOffset(-overlap1);
}
return digitsReturnValue;
} else if (overlap1 == segment.length()) {
// Partial exponent separator match
return true;
}
// No match
return false;
}
@Override
public UnicodeSet getLeadCodePoints() {
int leadCp = exponentSeparatorString.codePointAt(0);
UnicodeSet s = UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.SCIENTIFIC_LEAD);
if (s.contains(leadCp)) {
return s;
} else {
return new UnicodeSet().add(leadCp).freeze();
}
}
@Override
public void postProcess(ParsedNumber result) {
// No-op
}
@Override
public String toString() {
return "<ScientificMatcher " + exponentSeparatorString + ">";
}
}