1313 */
1414abstract class AbstractConfigurableFloatingPointBitsFromByteArrayAscii extends AbstractFloatValueParser {
1515 protected final ByteDigitSet digitSet ;
16- private final ByteSet minusSignChar ;
17- private final ByteSet plusSignChar ;
16+ private final ByteSet minusSign ;
17+ private final ByteSet plusSign ;
1818 private final ByteSet decimalSeparator ;
1919 private final ByteSet groupingSeparator ;
20- private final ByteTrie nanTrie ;
21- private final ByteTrie infinityTrie ;
22- private final ByteTrie exponentSeparatorTrie ;
20+ private final ByteTrie nan ;
21+ private final ByteTrie infinity ;
22+ private final ByteTrie exponentSeparator ;
2323
2424 public AbstractConfigurableFloatingPointBitsFromByteArrayAscii (NumberFormatSymbols symbols , boolean ignoreCase ) {
2525 this .decimalSeparator = ByteSet .copyOf (symbols .decimalSeparator (), ignoreCase );
2626 this .groupingSeparator = ByteSet .copyOf (symbols .groupingSeparator (), ignoreCase );
2727 this .digitSet = ByteDigitSet .copyOf (symbols .digits ());
28- this .minusSignChar = ByteSet .copyOf (symbols .minusSign (), ignoreCase );
29- this .exponentSeparatorTrie = ByteTrie .copyOf (symbols .exponentSeparator (), ignoreCase );
30- this .plusSignChar = ByteSet .copyOf (symbols .plusSign (), ignoreCase );
31- this .nanTrie = ByteTrie .copyOf (symbols .nan (), ignoreCase );
32- this .infinityTrie = ByteTrie .copyOf (symbols .infinity (), ignoreCase );
28+ this .minusSign = ByteSet .copyOf (symbols .minusSign (), ignoreCase );
29+ this .exponentSeparator = ByteTrie .copyOf (symbols .exponentSeparator (), ignoreCase );
30+ this .plusSign = ByteSet .copyOf (symbols .plusSign (), ignoreCase );
31+ this .nan = ByteTrie .copyOf (symbols .nan (), ignoreCase );
32+ this .infinity = ByteTrie .copyOf (symbols .infinity (), ignoreCase );
33+
3334 }
3435
3536 /**
@@ -43,14 +44,6 @@ public AbstractConfigurableFloatingPointBitsFromByteArrayAscii(NumberFormatSymbo
4344 */
4445 abstract long negativeInfinity ();
4546
46- private boolean isDecimalSeparator (byte ch ) {
47- return decimalSeparator .containsKey (ch );
48- }
49-
50- private boolean isGroupingSeparator (byte ch ) {
51- return groupingSeparator .containsKey (ch );
52- }
53-
5447 /**
5548 * Parses a {@code FloatingPointLiteral} production with optional leading and trailing
5649 * white space.
@@ -71,19 +64,15 @@ private boolean isGroupingSeparator(byte ch) {
7164 */
7265 public final long parseFloatingPointLiteral (byte [] str , int offset , int length ) {
7366 final int endIndex = checkBounds (str .length , offset , length );
74-
75- // Start at offset
76- // -------------------
7767 int index = offset ;
78- if (index == endIndex ) {
79- return SYNTAX_ERROR_BITS ;
80- }
8168 byte ch = str [index ];
8269
83- // Parse optional sign
70+ // Parse optional sign before significand
8471 // -------------------
85- final boolean isNegative = isMinusSign (ch );
86- if (isNegative || isPlusSign (ch )) {
72+ boolean isNegative = minusSign .containsKey (ch );
73+ boolean isSignificandSigned = false ;
74+ if (isNegative || plusSign .containsKey (ch )) {
75+ isSignificandSigned = true ;
8776 ++index ;
8877 if (index == endIndex ) {
8978 return SYNTAX_ERROR_BITS ;
@@ -107,11 +96,12 @@ public final long parseFloatingPointLiteral(byte[] str, int offset, int length)
10796 if (digit < 10 ) {
10897 // This might overflow, we deal with it later.
10998 significand = 10 * significand + digit ;
110- } else if (isDecimalSeparator (ch )) {
99+ } else if (decimalSeparator . containsKey (ch )) {
111100 illegal |= integerDigitCount >= 0 ;
112101 decimalSeparatorIndex = index ;
113102 integerDigitCount = index - significandStartIndex - groupingCount ;
114- } else if (isGroupingSeparator (ch )) {
103+ } else if (groupingSeparator .containsKey (ch )) {
104+ illegal |= decimalSeparatorIndex != -1 ;
115105 groupingCount ++;
116106 } else {
117107 break ;
@@ -130,37 +120,63 @@ public final long parseFloatingPointLiteral(byte[] str, int offset, int length)
130120 }
131121 illegal |= digitCount == 0 && significandEndIndex > significandStartIndex ;
132122
123+ // Parse optional sign after significand
124+ // -------------------
125+ if (index < endIndex && !isSignificandSigned ) {
126+ isNegative = minusSign .containsKey (ch );
127+ if (isNegative || plusSign .containsKey (ch )) {
128+ index ++;
129+ }
130+ }
131+
133132 // Parse exponent number
134133 // ---------------------
135134 int expNumber = 0 ;
136- int count = exponentSeparatorTrie .match (str , index , endIndex );
137- if (count > 0 ) {
138- index += count ;
139- ch = charAt (str , index , endIndex );
140- boolean isExponentNegative = isMinusSign (ch );
141- if (isExponentNegative || isPlusSign (ch )) {
142- ch = charAt (str , ++index , endIndex );
143- }
144- int digit = digitSet .toDigit (ch );
145- illegal |= digit >= 10 ;
146- do {
147- // Guard against overflow
148- if (expNumber < AbstractFloatValueParser .MAX_EXPONENT_NUMBER ) {
149- expNumber = 10 * expNumber + digit ;
135+ boolean isExponentSigned = false ;
136+ if (digitCount > 0 ) {
137+ int count = exponentSeparator .match (str , index , endIndex );
138+ if (count > 0 ) {
139+ index += count ;
140+
141+ // Parse optional sign before exponent number
142+ ch = charAt (str , index , endIndex );
143+ boolean isExponentNegative = minusSign .containsKey (ch );
144+ if (isExponentNegative || plusSign .containsKey (ch )) {
145+ ch = charAt (str , ++index , endIndex );
146+ isExponentSigned = true ;
150147 }
151- ch = charAt (str , ++index , endIndex );
152- digit = digitSet .toDigit (ch );
153- } while (digit < 10 );
154- if (isExponentNegative ) {
155- expNumber = -expNumber ;
148+
149+ int digit = digitSet .toDigit (ch );
150+ illegal |= digit >= 10 ;
151+ do {
152+ // Guard against overflow
153+ if (expNumber < AbstractFloatValueParser .MAX_EXPONENT_NUMBER ) {
154+ expNumber = 10 * expNumber + digit ;
155+ }
156+ ch = charAt (str , ++index , endIndex );
157+ digit = digitSet .toDigit (ch );
158+ } while (digit < 10 );
159+
160+
161+ // Parse optional sign after exponent number
162+ if (!isExponentSigned ) {
163+ isExponentNegative = minusSign .containsKey (ch );
164+ if (isExponentNegative || plusSign .containsKey (ch )) {
165+ index ++;
166+ }
167+ }
168+
169+ if (isExponentNegative ) {
170+ expNumber = -expNumber ;
171+ }
172+ exponent += expNumber ;
156173 }
157- exponent += expNumber ;
158174 }
159175
160176 // Parse NaN or Infinity (this occurs rarely)
161177 // ---------------------
162178 if (!illegal && digitCount == 0 ) {
163- return parseNaNOrInfinity (str , index , endIndex , isNegative );
179+ return parseNaNOrInfinity (str , index , endIndex , isNegative , isSignificandSigned );
164180 }
165181
166182 // Check if FloatingPointLiteral is complete
@@ -200,24 +216,29 @@ public final long parseFloatingPointLiteral(byte[] str, int offset, int length)
200216 exponentOfTruncatedSignificand , expNumber , offset , endIndex );
201217 }
202218
203- private boolean isMinusSign (byte c ) {
204- return minusSignChar .containsKey (c );
205- }
206-
207- private boolean isPlusSign (byte c ) {
208- return plusSignChar .containsKey (c );
209- }
210-
211- private long parseNaNOrInfinity (byte [] str , int index , int endIndex , boolean isNegative ) {
212- int nanMatch = nanTrie .match (str , index , endIndex );
219+ private long parseNaNOrInfinity (byte [] str , int index , int endIndex , boolean isNegative , boolean isSignificandSigned ) {
220+ int nanMatch = nan .match (str , index , endIndex );
213221 if (nanMatch > 0 ) {
214- if (index + nanMatch == endIndex ) {
215- return nan ();
222+ index += nanMatch ;
223+ if (index < endIndex && !isSignificandSigned ) {
224+ byte ch = str [index ];
225+ if (minusSign .containsKey (ch ) || plusSign .containsKey (ch )) {
226+ index ++;
227+ }
216228 }
229+ return (index == endIndex ) ? nan () : SYNTAX_ERROR_BITS ;
217230 }
218- int infinityMatch = infinityTrie .match (str , index , endIndex );
231+ int infinityMatch = infinity .match (str , index , endIndex );
219232 if (infinityMatch > 0 ) {
220- if (index + infinityMatch == endIndex ) {
233+ index += infinityMatch ;
234+ if (index < endIndex && !isSignificandSigned ) {
235+ byte ch = str [index ];
236+ isNegative = minusSign .containsKey (ch );
237+ if (isNegative || plusSign .containsKey (ch )) {
238+ index ++;
239+ }
240+ }
241+ if (index == endIndex ) {
221242 return isNegative ? negativeInfinity () : positiveInfinity ();
222243 }
223244 }
0 commit comments