@@ -20,12 +20,12 @@ import scala.annotation.tailrec
20
20
*/
21
21
private [scala] object StringParsers {
22
22
23
- // compile-time constant helpers
23
+ // compile-time constant helpers
24
24
25
- // Int.MinValue == -2147483648
25
+ // Int.MinValue == -2147483648
26
26
private final val intOverflowBoundary = - 214748364
27
27
private final val intOverflowDigit = 9
28
- // Long.MinValue == -9223372036854775808L
28
+ // Long.MinValue == -9223372036854775808L
29
29
private final val longOverflowBoundary = - 922337203685477580L
30
30
private final val longOverflowDigit = 9
31
31
@@ -56,23 +56,23 @@ private[scala] object StringParsers {
56
56
@ inline
57
57
private [this ] final def isDigit (c : Char ): Boolean = c >= '0' && c <= '9'
58
58
59
- // bool
59
+ // bool
60
60
@ inline
61
61
final def parseBool (from : String ): Option [Boolean ] =
62
62
if (from.equalsIgnoreCase(" true" )) Some (true )
63
63
else if (from.equalsIgnoreCase(" false" )) Some (false )
64
64
else None
65
65
66
- // integral types
66
+ // integral types
67
67
final def parseByte (from : String ): Option [Byte ] = {
68
68
val len = from.length()
69
- // empty strings parse to None
69
+ // empty strings parse to None
70
70
if (len == 0 ) None
71
71
else {
72
72
val first = from.charAt(0 )
73
73
val v = decValue(first)
74
74
if (len == 1 ) {
75
- // "+" and "-" parse to None
75
+ // "+" and "-" parse to None
76
76
if (v > - 1 ) Some (v.toByte)
77
77
else None
78
78
} else if (v > - 1 ) stepToOverflow(from, len, - v, true , Byte .MinValue ).map(_.toByte)
@@ -84,13 +84,13 @@ private[scala] object StringParsers {
84
84
85
85
final def parseShort (from : String ): Option [Short ] = {
86
86
val len = from.length()
87
- // empty strings parse to None
87
+ // empty strings parse to None
88
88
if (len == 0 ) None
89
89
else {
90
90
val first = from.charAt(0 )
91
91
val v = decValue(first)
92
92
if (len == 1 ) {
93
- // "+" and "-" parse to None
93
+ // "+" and "-" parse to None
94
94
if (v > - 1 ) Some (v.toShort)
95
95
else None
96
96
} else if (v > - 1 ) stepToOverflow(from, len, - v, true , Short .MinValue ).map(_.toShort)
@@ -116,13 +116,13 @@ private[scala] object StringParsers {
116
116
else step(i + 1 , (agg * 10 ) - digit, isPositive)
117
117
}
118
118
}
119
- // empty strings parse to None
119
+ // empty strings parse to None
120
120
if (len == 0 ) None
121
121
else {
122
122
val first = from.charAt(0 )
123
123
val v = decValue(first)
124
124
if (len == 1 ) {
125
- // "+" and "-" parse to None
125
+ // "+" and "-" parse to None
126
126
if (v > - 1 ) Some (v)
127
127
else None
128
128
} else if (v > - 1 ) step(1 , - v, true )
@@ -133,7 +133,7 @@ private[scala] object StringParsers {
133
133
}
134
134
135
135
final def parseLong (from : String ): Option [Long ] = {
136
- // like parseInt, but Longer
136
+ // like parseInt, but Longer
137
137
val len = from.length()
138
138
139
139
@ tailrec
@@ -149,13 +149,13 @@ private[scala] object StringParsers {
149
149
else step(i + 1 , agg * 10 - digit, isPositive)
150
150
}
151
151
}
152
- // empty strings parse to None
152
+ // empty strings parse to None
153
153
if (len == 0 ) None
154
154
else {
155
155
val first = from.charAt(0 )
156
156
val v = decValue(first).toLong
157
157
if (len == 1 ) {
158
- // "+" and "-" parse to None
158
+ // "+" and "-" parse to None
159
159
if (v > - 1 ) Some (v)
160
160
else None
161
161
} else if (v > - 1 ) step(1 , - v, true )
@@ -165,24 +165,24 @@ private[scala] object StringParsers {
165
165
}
166
166
}
167
167
168
- // floating point
168
+ // floating point
169
169
final def checkFloatFormat (format : String ): Boolean = {
170
- // indices are tracked with a start index which points *at* the first index
171
- // and an end index which points *after* the last index
172
- // so that slice length === end - start
173
- // thus start == end <=> empty slice
174
- // and format.substring(start, end) is equivalent to the slice
170
+ // indices are tracked with a start index which points *at* the first index
171
+ // and an end index which points *after* the last index
172
+ // so that slice length === end - start
173
+ // thus start == end <=> empty slice
174
+ // and format.substring(start, end) is equivalent to the slice
175
175
176
- // some utilities for working with index bounds into the original string
176
+ // some utilities for working with index bounds into the original string
177
177
@ inline
178
178
def forAllBetween (start : Int , end : Int , pred : Char => Boolean ): Boolean = {
179
179
@ tailrec
180
180
def rec (i : Int ): Boolean = i >= end || pred(format.charAt(i)) && rec(i + 1 )
181
181
rec(start)
182
182
}
183
183
184
- // one after last index for the predicate to hold, or `from` if none hold
185
- // may point after the end of the string
184
+ // one after last index for the predicate to hold, or `from` if none hold
185
+ // may point after the end of the string
186
186
@ inline
187
187
def skipIndexWhile (predicate : Char => Boolean , from : Int , until : Int ): Int = {
188
188
@ tailrec @ inline
@@ -201,20 +201,21 @@ private[scala] object StringParsers {
201
201
def prefixOK (startIndex : Int , endIndex : Int ): Boolean = {
202
202
val len = endIndex - startIndex
203
203
(len > 0 ) && {
204
- // the prefix part is
205
- // hexDigits
206
- // hexDigits.
207
- // hexDigits.hexDigits
208
- // .hexDigits
209
- // but not .
204
+ // the prefix part is
205
+ // hexDigits
206
+ // hexDigits.
207
+ // hexDigits.hexDigits
208
+ // .hexDigits
209
+ // but not .
210
210
if (format.charAt(startIndex) == '.' ) {
211
211
(len > 1 ) && forAllBetween(startIndex + 1 , endIndex, isHexDigit)
212
212
} else {
213
213
val noLeading = skipIndexWhile(isHexDigit, startIndex, endIndex)
214
214
(noLeading >= endIndex) ||
215
- ((format.charAt(noLeading) == '.' ) && forAllBetween(noLeading + 1 ,
216
- endIndex,
217
- isHexDigit))
215
+ ((format.charAt(noLeading) == '.' ) && forAllBetween(
216
+ noLeading + 1 ,
217
+ endIndex,
218
+ isHexDigit))
218
219
}
219
220
}
220
221
}
@@ -234,7 +235,7 @@ private[scala] object StringParsers {
234
235
}
235
236
236
237
def isDecFloatLiteral (startIndex : Int , endIndex : Int ): Boolean = {
237
- // invariant: endIndex > startIndex
238
+ // invariant: endIndex > startIndex
238
239
239
240
def isExp (c : Char ): Boolean = c == 'e' || c == 'E'
240
241
@@ -247,57 +248,59 @@ private[scala] object StringParsers {
247
248
else skipIndexWhile(isDigit, startIndex, endIndex) == endIndex
248
249
}
249
250
250
- // significant can be one of
251
- // * digits.digits
252
- // * .digits
253
- // * digits.
254
- // but not just .
251
+ // significant can be one of
252
+ // * digits.digits
253
+ // * .digits
254
+ // * digits.
255
+ // but not just .
255
256
val startChar = format.charAt(startIndex)
256
257
if (startChar == '.' ) {
257
258
val noSignificant = skipIndexWhile(isDigit, startIndex + 1 , endIndex)
258
259
// a digit is required followed by optional exp
259
260
(noSignificant > startIndex + 1 ) && (noSignificant >= endIndex ||
260
- isExp(format.charAt(noSignificant)) && expOK(noSignificant + 1 , endIndex))
261
+ isExp(format.charAt(noSignificant)) && expOK(noSignificant + 1 , endIndex))
261
262
} else if (isDigit(startChar)) {
262
263
// one set of digits, then optionally a period, then optionally another set of digits, then optionally an exponent
263
264
val noInt = skipIndexWhile(isDigit, startIndex, endIndex)
264
265
// just the digits
265
266
(noInt == endIndex) || {
266
267
if (format.charAt(noInt) == '.' ) {
267
268
val noSignificant = skipIndexWhile(isDigit, noInt + 1 , endIndex)
268
- (noSignificant >= endIndex) || // no exponent
269
+ (noSignificant >= endIndex) || // no exponent
269
270
isExp(format.charAt(noSignificant)) && expOK(noSignificant + 1 , endIndex)
270
271
} else
271
272
isExp(format.charAt(noInt)) && expOK(noInt + 1 , endIndex)
272
273
}
273
274
} else false
274
275
}
275
276
276
- // count 0x00 to 0x20 as "whitespace", and nothing else
277
+ // count 0x00 to 0x20 as "whitespace", and nothing else
277
278
val unspacedStart = format.indexWhere(ch => ch.toInt > 0x20 )
278
279
val unspacedEnd = format.lastIndexWhere(ch => ch.toInt > 0x20 ) + 1
279
280
280
281
if (unspacedStart == - 1 || unspacedStart >= unspacedEnd || unspacedEnd <= 0 ) false
281
282
else {
282
- // all formats can have a sign
283
+ // all formats can have a sign
283
284
val unsigned = {
284
285
val startchar = format.charAt(unspacedStart)
285
286
if (startchar == '-' || startchar == '+' ) unspacedStart + 1 else unspacedStart
286
287
}
287
288
if (unsigned >= unspacedEnd) false
288
- // that's it for NaN and Infinity
289
+ // that's it for NaN and Infinity
289
290
else if (format.charAt(unsigned) == 'N' ) format.substring(unsigned, unspacedEnd) == " NaN"
290
291
else if (format.charAt(unsigned) == 'I' ) format.substring(unsigned, unspacedEnd) == " Infinity"
291
292
else {
292
- // all other formats can have a format suffix
293
+ // all other formats can have a format suffix
293
294
val desuffixed = {
294
295
val endchar = format.charAt(unspacedEnd - 1 )
295
296
if (endchar == 'f' || endchar == 'F' || endchar == 'd' || endchar == 'D' ) unspacedEnd - 1
296
297
else unspacedEnd
297
298
}
298
299
val len = desuffixed - unsigned
299
300
if (len <= 0 ) false
300
- else if (len >= 2 && (format.charAt(unsigned + 1 ) == 'x' || format.charAt(unsigned + 1 ) == 'X' ))
301
+ else if (
302
+ len >= 2 && (format.charAt(unsigned + 1 ) == 'x' || format.charAt(unsigned + 1 ) == 'X' )
303
+ )
301
304
format.charAt(unsigned) == '0' && isHexFloatLiteral(unsigned + 2 , desuffixed)
302
305
else isDecFloatLiteral(unsigned, desuffixed)
303
306
}
0 commit comments