@@ -35,16 +35,14 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3535
3636// TODO: make separate implementation for streaming and non-streaming
3737class IterImplNumber {
38-
38+
3939 final static int [] digits = new int [256 ];
4040 private final static int [] intDigits = new int [256 ];
4141 private final static int [] floatDigits = new int [256 ];
4242 private final static int END_OF_NUMBER = -2 ;
4343 private final static int DOT_IN_NUMBER = -3 ;
4444 private final static int INVALID_CHAR_FOR_NUMBER = -1 ;
4545 private static final int POW10 [] = {1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 };
46- private final static long LONG_SAFE_TO_MULTIPLY_10 = (Long .MAX_VALUE / 10 ) - 1 ;
47- private final static int INT_SAFE_TO_MULTIPLY_10 = (Integer .MAX_VALUE / 10 ) - 1 ;
4846
4947 static {
5048 for (int i = 0 ; i < digits .length ; i ++) {
@@ -97,10 +95,11 @@ private static final double readPositiveDouble(final JsonIterator iter) throws I
9795 case DOT_IN_NUMBER :
9896 break non_decimal_loop ;
9997 }
100- if (value > LONG_SAFE_TO_MULTIPLY_10 ) {
98+ value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
99+ if (value < 0 ) {
100+ // overflow
101101 return readDoubleSlowPath (iter );
102102 }
103- value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
104103 }
105104 if (c == '.' ) {
106105 i ++;
@@ -121,10 +120,11 @@ private static final double readPositiveDouble(final JsonIterator iter) throws I
121120 return readDoubleSlowPath (iter );
122121 }
123122 decimalPlaces ++;
124- if (value > LONG_SAFE_TO_MULTIPLY_10 ) {
123+ value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
124+ if (value < 0 ) {
125+ // overflow
125126 return readDoubleSlowPath (iter );
126127 }
127- value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
128128 }
129129 }
130130 return readDoubleSlowPath (iter );
@@ -165,10 +165,11 @@ private static final float readPositiveFloat(final JsonIterator iter) throws IOE
165165 case DOT_IN_NUMBER :
166166 break non_decimal_loop ;
167167 }
168- if (value > LONG_SAFE_TO_MULTIPLY_10 ) {
168+ value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
169+ if (value < 0 ) {
170+ // overflow
169171 return readFloatSlowPath (iter );
170172 }
171- value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
172173 }
173174 if (c == '.' ) {
174175 i ++;
@@ -189,10 +190,11 @@ private static final float readPositiveFloat(final JsonIterator iter) throws IOE
189190 return readFloatSlowPath (iter );
190191 }
191192 decimalPlaces ++;
192- if (value > LONG_SAFE_TO_MULTIPLY_10 ) {
193+ value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
194+ if (value < 0 ) {
195+ // overflow
193196 return readFloatSlowPath (iter );
194197 }
195- value = (value << 3 ) + (value << 1 ) + ind ; // value = value * 10 + ind;
196198 }
197199 }
198200 return readFloatSlowPath (iter );
@@ -208,7 +210,7 @@ public static final float readFloatSlowPath(final JsonIterator iter) throws IOEx
208210
209211 public static final String readNumber (final JsonIterator iter ) throws IOException {
210212 int j = 0 ;
211- for (;; ) {
213+ for (; ; ) {
212214 for (int i = iter .head ; i < iter .tail ; i ++) {
213215 if (j == iter .reusableChars .length ) {
214216 char [] newBuf = new char [iter .reusableChars .length * 2 ];
@@ -247,111 +249,89 @@ public static final String readNumber(final JsonIterator iter) throws IOExceptio
247249 public static final int readInt (final JsonIterator iter ) throws IOException {
248250 byte c = IterImpl .nextToken (iter );
249251 if (c == '-' ) {
250- return readNegativeInt (iter );
252+ return - readPositiveInt (iter , IterImpl . readByte ( iter ) );
251253 } else {
252254 return readPositiveInt (iter , c );
253255 }
254256 }
255257
256258 public static final int readPositiveInt (final JsonIterator iter , byte c ) throws IOException {
257- int value = intDigits [c ];
258- if (value == 0 ) {
259+ int ind = intDigits [c ];
260+ if (ind == 0 ) {
259261 return 0 ;
260262 }
261- if (value == INVALID_CHAR_FOR_NUMBER ) {
263+ if (ind == INVALID_CHAR_FOR_NUMBER ) {
262264 throw iter .reportError ("readPositiveInt" , "expect 0~9" );
263265 }
264- for (;;) {
266+ int value = ind ;
267+ for (; ; ) {
265268 for (int i = iter .head ; i < iter .tail ; i ++) {
266- int ind = intDigits [iter .buf [i ]];
269+ ind = intDigits [iter .buf [i ]];
267270 if (ind == INVALID_CHAR_FOR_NUMBER ) {
268271 iter .head = i ;
269272 return value ;
270273 }
271- if (value > INT_SAFE_TO_MULTIPLY_10 ) {
272- int value2 = (value << 3 ) + (value << 1 ) + ind ;
273- if (value2 < INT_SAFE_TO_MULTIPLY_10 * 10 ) {
274- throw iter .reportError ("readPositiveInt" , "value is too large for int" );
274+ value = (value << 3 ) + (value << 1 ) + ind ;
275+ if (value < 0 ) {
276+ // overflow
277+ if (value == Integer .MIN_VALUE ) {
278+ // if there is more number following, subsequent read will fail anyway
279+ iter .head = i ;
280+ return value ;
275281 } else {
276- value = value2 ;
277- continue ;
282+ throw iter .reportError ("readPositiveInt" , "value is too large for int" );
278283 }
279284 }
280- value = (value << 3 ) + (value << 1 ) + ind ;
281285 }
282286 if (!IterImpl .loadMore (iter )) {
283287 return value ;
284288 }
285289 }
286290 }
287291
288- public static final int readNegativeInt (final JsonIterator iter ) throws IOException {
289- byte c = IterImpl .readByte (iter );
292+ public static final long readLong (JsonIterator iter ) throws IOException {
293+ byte c = IterImpl .nextToken (iter );
294+ if (c == '-' ) {
295+ return -readPositiveLong (iter , IterImpl .readByte (iter ));
296+ } else {
297+ return readPositiveLong (iter , c );
298+ }
299+ }
300+
301+ public static final long readPositiveLong (final JsonIterator iter , byte c ) throws IOException {
290302 int ind = intDigits [c ];
291303 if (ind == 0 ) {
292304 return 0 ;
293305 }
294306 if (ind == INVALID_CHAR_FOR_NUMBER ) {
295- throw iter .reportError ("readNegativeInt " , "expect 0~9" );
307+ throw iter .reportError ("readPositiveInt " , "expect 0~9" );
296308 }
297- int value = - ind ;
298- for (;; ) {
309+ long value = ind ;
310+ for (; ; ) {
299311 for (int i = iter .head ; i < iter .tail ; i ++) {
300312 ind = intDigits [iter .buf [i ]];
301313 if (ind == INVALID_CHAR_FOR_NUMBER ) {
302314 iter .head = i ;
303315 return value ;
304316 }
305- if (value > INT_SAFE_TO_MULTIPLY_10 ) {
306- int value2 = (value << 3 ) + (value << 1 ) - ind ;
307- if (value2 < INT_SAFE_TO_MULTIPLY_10 * 10 ) {
308- throw iter .reportError ("readNegativeInt" , "value is too large for int" );
317+ value = (value << 3 ) + (value << 1 ) + ind ;
318+ if (value < 0 ) {
319+ // overflow
320+ if (value == Long .MIN_VALUE ) {
321+ // if there is more number following, subsequent read will fail anyway
322+ iter .head = i ;
323+ return value ;
309324 } else {
310- value = value2 ;
311- continue ;
325+ throw iter .reportError ("readPositiveLong" , "value is too large for long" );
312326 }
313327 }
314- value = (value << 3 ) + (value << 1 ) - ind ;
315328 }
316329 if (!IterImpl .loadMore (iter )) {
317330 return value ;
318331 }
319332 }
320333 }
321334
322- public static final long readLong (JsonIterator iter ) throws IOException {
323- byte c = IterImpl .nextToken (iter );
324- if (c == '-' ) {
325- return -readUnsignedLong (iter );
326- } else {
327- iter .unreadByte ();
328- return readUnsignedLong (iter );
329- }
330- }
331-
332- public static final long readUnsignedLong (JsonIterator iter ) throws IOException {
333- // TODO: throw overflow
334- byte c = IterImpl .readByte (iter );
335- int v = digits [c ];
336- if (v == 0 ) {
337- return 0 ;
338- }
339- if (v == -1 ) {
340- throw iter .reportError ("readUnsignedLong" , "expect 0~9" );
341- }
342- long result = 0 ;
343- for (; ; ) {
344- result = result * 10 + v ;
345- c = IterImpl .readByte (iter );
346- v = digits [c ];
347- if (v == -1 ) {
348- iter .unreadByte ();
349- break ;
350- }
351- }
352- return result ;
353- }
354-
355335 public static final char readU4 (JsonIterator iter ) throws IOException {
356336 int v = digits [IterImpl .readByte (iter )];
357337 if (v == -1 ) {
0 commit comments