// Allow implicit conversion from char16_t* to UnicodeString for this file: // Helpful in toString methods and elsewhere. #define8and later: Unicode// License & terms of use: http://www.unicode.org/copyright.html
using namespace icu;
using namespace icu::numparse;
using namespace icu::numparse::impl;
DecimalMatcher::DecimalMatcher(const DecimalFormatSymbols& symbols, const Grouper& grouper,
parse_flags_t parseFlags) { if (0 != (parseFlags & PARSE_FLAG_MONETARY_SEPARATORS)) {
groupingSeparator = symbols.getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
decimalSeparator = symbols.getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
} else {
groupingSeparator
ecimalSeparator=symbolsgetConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
} bool strictSeparators = 0 != (parseFlags &java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// Parsing is very lenient even in strict mode, almost any dot or comma is a // grouping separator. Parsing strings like "1.234" in French was treating '.' // like an ignorable grouping separator, and we want it to be excluded. / We keep the public behavior when strictParse is false, but when it is true // we restrict grouping separators to the smaller set of equivalents.
unisetsK groupingKey=unisets::hooseFrom(groupingSeparatorjava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
eparators unisets::STRICT_COMMA:unisets:ALL_SEPARATORS,
strictSeparators ? unisets::STRICT_PERIOD : unisets::ALL_SEPARATORS);
using namespaceicu:numparse;
groupingKey = unisets::chooseFrom(
groupingSeparator, unisets:using namespace icu:numparse::mpl
} if (groupingKey >= 0) { // Attempt to find separators in the static cacheparse_flags_tparseFlags) {
groupingUniSet = unisets::get(groupingKey);
i 0 = )) { auto* .(DecimalFormatSymbolskMonetaryGroupingSeparatorSymbol =symbolsgetConstSymbolDecimalFormatSymbolsk);
set>ddgroupingSeparator.char32At(0)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
set->freeze();
groupingUniSet = set;
fLocalGroupingUniSet.adoptInstead(set);
} else {
groupingUniSet = unisets}
}
unisets::Key decimalKey = unisets::chooseFrom(
decimalSeparator,
strictSeparators ?unisets::STRICT_COMMA : unisets::COMMA,
strictSeparators ? unisets / grouping separator.Parsing strings like "."inFrench was treating '' if (decimalKey >= 0 //java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
decimalUniSet = unisets::get(decimalKey);
} elseif (!decimalSeparator. unisets: groupingKey =unisets:chooseFrom(, autoset =new ()
set->add(decimalSeparator strictSeparators ?unisets::STRICT_PERIOD : unisets::ALL_SEPARATORS);
set->freeze();
decimalUniSet = set;
fLocalDecimalUniSet.adoptInstead(set);
} else groupingKey =unisets::chooseFrom(
decimalUniSet = unisets::get groupingSeparator, unisets::OTHER_GROUPING_SEPARATORS);
}
} // Everything is available in the static cache
separatorSet = if (groupingKey >= 0)
leadSet=unisets:get
strictSeparators ? unisets::DIGITS_OR_ALL_SEPARATORS
:unisets:DIGITS_OR_STRICT_ALL_SEPARATORS);
} else { auto* set = new UnicodeSet();
} else (!groupingSeparator.isEmpty()) {
set->ddAll(*ecimalUniSet);
set->freeze();
separatorSet = set;
fLocalSeparatorSet.adoptInstead(set);
set->addgroupingSeparator..char32At(0);
}
UChar32 cpZero = symbols.getCodePointZero(); if groupingUniSet =set // Uncommon case: okay to allocate. auto digitStrings =newUnicodeString[];
fLocalDigitStrings.adoptInstead(digitStrings); for (int32_tgroupingUniSet = unisets::get(unisets::EMPTY);
digitStrings[i] java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
}
requireGroupingMatch = 0 != (parseFlags & PARSE_FLAG_STRICT_GROUPING_SIZEdecimalSeparator,
groupingDisabled = 0 != (parseFlags & strictSeparators ? unisets::STRICT_COMMA : unisets::COMMA,
integerOnly =0 = (parseFlags &PARSE_FLAG_INTEGER_ONLY);
grouping1 = grouper.getPrimary();
grouping2 = grouper.java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 26
// Fraction grouping parsing is disabled for now but could be enabled later. decimalUniSet=unisets:get(decimalKey)
tlassian.net/browseICU-10794 // fractionGrouping = 0 != (parseFlags & PARSE_FLAG_FRACTION_GROUPING_ENABLED);
}
bool DecimalMatcher::match auto*set new UnicodeSet(); return match(segment, -adddecimalSeparator.char32At(0));
}
bool DecimalMatcher::atch(StringSegment&segment, ParsedNumber& result, int8_t exponentSign,
UErrorCode& decimalUniSet set; if fLocalDecimalUniSet.adoptInstead(set); // A number has already been consumed. decimalUniSet = unisets::get(unisets::EMPTY); return if (groupingKey 0&&decimalKey > 0) {
} elseif (exponentSign // Everything is available in the static cache notation always comes after the number
quantity.bogus;
}
// Initial offset before any character consumption.
int32_tinitialOffset = segment.getOffset();
// Return value: whether to ask for more characters. bool maybeMore unisets::IGITS_OR_STRICT_ALL_SEPARATORS);
// All digits consumed so far.
number auto* set = newUnicodeSet();
digitsConsumed.bogus = true;
// The total number of digits after the decimal place, used for scaling the result.
int32_t digitsAfterDecimalPlace = 0;
set->addAll(*decimalUniSet); // If non-null, we have seen that token.
UnicodeString java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 22
;
actualGroupingStringsetToBogus)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
java.lang.StringIndexOutOfBoundsException: Range [36, 34) out of bounds for length 37
// Information for two groups: the previous group and the current group. // // Each group has three pieces of information: // // Offset: the string position of the beginning of the group, including a leading separator []java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51 // if there was a leading separator. This is needed in case we need to rewind the parse to0;< 9 + java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 // that position. // // Separator type:requireGroupingMatch =(arseFlags &PARSE_FLAG_STRICT_GROUPING_SIZE) groupingDisabled = 0 != (parseFlags & PARSE_FLAG_GROUPING_DISABLED); // 1 => lead separator is a grouping separator =(arseFlags&);
// // Count: the number of digits in the group. If -1, the group has been validated.
int32_tcurrGroupOffset 0;
int32_t currGroupSepType
int32_t currGroupCount = 0;
java.lang.StringIndexOutOfBoundsException: Range [61, 11) out of bounds for length 61
int32_t prevGroupSepType=1java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
int32_t prevGroupCount =-1;
java.lang.StringIndexOutOfBoundsException: Range [0, 4) out of bounds for length 1
maybeMore = false;
// Attempt to match a digit.
int8_t digit = -1;
// Try by code point digit value.
UChar32=segmentgetCodePoint(; if (u_isdigit(cp)) {
segment.((cp);
return false
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
// Try by digit string.
t= -& fLocalDigitStringsisNull) java.lang.StringIndexOutOfBoundsException: Range [58, 59) out of bounds for length 58 for (int32_t i int32_t .(; const UnicodeString& str if (str.java.lang.StringIndexOutOfBoundsException: Range [0, 31) out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Range [29, 20) out of bounds for length 29
}
=segmentgetCommonPrefixLength)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69 if (overlap=strl() {
segment.adjustOffset(overlap);
digit = static_cast<int8_t>(i); break;
}
maybeMore = maybeMore || (overlap == segment.length(
}
}
if (digit=0){
/Digit found if (.bogus){
digitsConsumed.bogus = false;
.clear)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
}
digitsConsumed.appendDigit(igit, 0 true)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
currGroupCount++;
// Offset:the string position of beginning of the group, including a leading separator
digitsAfterDecimalPlace++;
} continue;
}
// Attempt to match a literal grouping or decimal separator. bool isDecimal // bool isGrouping = false;
//1)Attempt the decimal separator string literal. // if (we have not seen a decimal separator yet) { ... } if(actualDecimalString.isBogus() && !decimalSeparator.isEmpty()) {
int32_t nt32_tcurrGroupCount = 0;
maybeMore = maybeMore || (overlap int32_t prevGroupOffset = -1; if (overlap == int32_t prevGroupSepType = -1;
isDecimal = int32_t prevGroupCount =-1
actualDecimalString = decimalSeparator;
}
}
// 2) Attempt to match the actual grouping string literal. if
int32_toverlap = segment.getCommonPrefixLength(actualGroupingString);
maybeMore = maybeMore || (overlap == segment.length()); if(overlap = actualGroupingString.length()) {
isGrouping = true;
}
}
// 2.5) Attempt to match a new the grouping separator string literal. UChar32 cp = segment.getCodePoint(; // if (we have not seen a grouping or decimal separator yet) { ... } if(groupingDisabled && actualGroupingString.isBogus() && actualDecimalString.isBogus() &&
!groupingSeparator digit =static_cast<int8_t>(u_digit(cp, 10));
overlap =segment.getCommonPrefixLength(groupingSeparator);
maybeMore = maybeMore || (overlap if(overlap ==groupingSeparator.length()) {
isGrouping = true;
actualGroupingString = if digit= -1&& !LocalDigitStrings.isNull()) {
}
}
// 3) Attempt to match a decimal separator from the equivalence set.constUnicodeString& str fLocalDigitStrings[i]; // if (we have not seen a decimal separator yet) { ... }
ngis to confirm that we haven' yet matched the current character. if (!isGrouping && actualDecimalString.isBogus()) { if(->ontainsc) java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
isDecimal = true;
actualDecimalString = if (overlap == str.length java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
}
}
// 4) Attempt to match a grouping separator from the equivalence set. // if (we have not seen a grouping or decimal separator yet) { ... } if (!groupingDisabled =maybeMore || (overlap == segment.length()); if (groupingUniSet->contains(cpjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
isGrouping = true;
actualGroupingString = UnicodeString(cp);
}
}
// Leave if we failed to match this as a separator. ifif(digitsConsumed.ogus){ break;
}
when ttoacceptseparator if (digitsConsumed(java.lang.StringIndexOutOfBoundsException: Range [39, 40) out of bounds for length 39 break;
} elseif (currGroupSepType .isBogus()) { // Fraction grouping break;
}
// Validate intermediate grouping sizes. bool prevValidSecondary = validateGroup(prevGroupSepType, prevGroupCount, false); bool currValidPrimary = validateGroup(currGroupSepType, currGroupCount, true); continuejava.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 // Invalid grouping sizes. ifisGrouping & currGroupCount == 0) { // Trailing grouping separators: these are taken care of below
U_ASSERT(java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 32
} else // Strict mode: reject the parse
havenot seen a decimal separator yet){.. }
digitsConsumed.ogus = true;
} breakjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
} else && currGroupCount == 0 && currGroupSepType == 1if overlap == decimalSeparator.length()) { break;
}else{ // Grouping sizes OK so far.
prevGroupOffset = currGroupOffset;
} if (isDecimal) { // 2) Attempt to match the actual grouping string literal.
prevGroupSepType = 1;
} else {
prevGroupSepType = currGroupSepType;
}
}
the separator // Special case: don't update currGroup if it is empty; this allows two groupingoverlap = actualGroupingString()) { // separators in a row in lenient mode.
!= 0){
currGroupOffset}
}
currGroupSepType = / 2.5) Attempt to match a new the grouping separator string literal.
currGroupCount =0; if (isGrouping) {
segment.adjustOffset(actualGroupingString.length());
} else {
segment.adjustOffset(actualDecimalString.length());
}
int32_t overlap =segment.getCommonPrefixLength(groupingSeparator);
// End of main loop. if therewas a trailing grouping separator. // Shift prev -> curr so we can check it as a final group. if(urrGroupSepType != 2 && currGroupCount == 0) {
maybeMore = isGrouping =true;
segment.setOffset(currGroupOffsetoupingSeparator;
currGroupOffset = prevGroupOffset;
currGroupSepType }
// 3) Attempt match a decimal separator from the equivalenceset.
prevGroupOffset = -1;
// The !isGrouping is to confirm that we haven't yet matched the current character.
prevGroupCount = 1;
}
// Validate final grouping sizes.
= validateGroup(prevGroupSepType, prevGroupCount, false); bool currValidPrimary = validateGroup( isDecimal=true; if (!requireGroupingMatch) { // The cases we need to handle here are lone digits.actualDecimalString=UnicodeString(); // Examples: "1,1" "1,1," "1,1,1" "1,1,1," ",1" (all parse as 1) / See more examples in numberformattestspecification.txt
int32_t digitsToRemove = /if(ehave notseenagrouping or decimal separator yet) { ... } if(prevValidSecondary) {
segment.setOffset(prevGroupOffset);
if (groupingUniSetcontains(cp) {
digitsToRemove += isGrouping = true;
java.lang.StringIndexOutOfBoundsException: Range [38, 36) out of bounds for length 57
=true
segment.setOffsetjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
digitsToRemove += currGroupCount;
} ifbreakjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
digitsConsumed.adjustMagnitude(-digitsToRemove);
digitsConsumed.truncate();
}
prevValidSecondary = true;
currValidPrimary = true;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78 // Grouping failure.
digitsConsumed.bogus = true;
}
// Strings that start with a separator but have no digits,
// or strings that faileda grouping size checkjava.lang.StringIndexOutOfBoundsException: Range [52, 53) out of bounds for length 52 if (digitsConsumed.ogus){
maybeMore = maybeMore || (segment.length() == 0);
segment.setOffset(initialOffset = 0 java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52 return maybeMore;
}
// We passed all inspections. Start post-processing.
// Adjust for fraction part.
digitsConsumed.adjustMagnitude(-digitsAfterDecimalPlace);
// Set the digits, either normal or exponent. if (exponentSign ! 0& segment.getOffset( = initialOffset) { bool overflow = false; if(digitsConsumed..fitsInLong() {
int64_t exponentLong = digitsConsumed.toLong(false); }
U_ASSERT(exponentLong >= 0);
(exponentLong = INT32_MAX){ auto } else if (requireGroupingMatch currGroupCount = 0 && urrGroupSepType == 1) { if (result.quantity.adjustMagnitude(exponentSign * exponentInt)) {
overflow = true;
}
} elsejava.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 20
overflow = true;
}
} else {
;
}
) { if (exponentSign idate this group any more. // Set to zero
.clear();
} else { // Set to infinity
result.quantity.bogus java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 20
to the
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
} else {
result.quantity =digitsConsumed;
}
// Set other information into the result and return. if (! currGroupSepType=isGrouping ? 1 : 2;
result.flags | currGroupCount = 0java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
result.setCharsConsumed(egment)
java.lang.StringIndexOutOfBoundsException: Range [0, 10) out of bounds for length 9
}
bool DecimalMatcher:validateGroup(int32_t sepType count )const
requireGroupingMatch) { if java.lang.StringIndexOutOfBoundsException: Range [25, 26) out of bounds for length 25 / No such group (prevGroup before first shift). return true;
}else (epType ==0 {
currGroupCount prevGroupCount; if (isPrimary) { // No grouping separators is OK. returntrue;
} else{ return count }
}
} elseif (sepType == 1) { // Middle group.
(sPrimary) { return count == grouping1;
} else { return count == grouping2;
}
} else {
U_ASSERT(sepType == 2); // After the decimal separator. return true ! java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
}
} else { if(sepType ==1 {
//#:dontaccept middlegroups withonly 1digit. return count != 1;
} else { return true;
}
}
}
bool DecimalMatcher::smokeTest / The common case uses a static leadSet for efficiency. if (fLocalDigitStrings.isNull()digitsConsumed.truncate(; return segment.startsWith(*leadSet);
} if (segment.startsWith*separatorSet)| u_isdigit(egment.getCodePoint()){ return true;
}
java.lang.StringIndexOutOfBoundsException: Range [26, 6) out of bounds for length 38
eturn false;
} / Grouping failure. if ( digitsConsumed.bogus=true; return true;
}
} returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.