in cayenne/src/main/java/org/apache/cayenne/value/json/JsonTokenizer.java [213:349]
private JsonToken numericValue() {
checkValueState(data[position]);
/*
* number
* integer fraction exponent
*
* integer
* digit
* onenine digits
* '-' digit
* '-' onenine digits
*
* digits
* digit
* digit digits
*
* digit
* '0'
* onenine
*
* onenine
*
*
* fraction
* ""
* '.' digits
*
* exponent
* ""
* 'E' sign digits
* 'e' sign digits
*
* sign
* ""
* '+'
* '-'
*/
int startPosition = position;
NumberState state = NumberState.NONE;
while (state != NumberState.DONE) {
switch (data[position]) {
case '0':
if(state == NumberState.NONE
|| state == NumberState.MINUS) {
state = NumberState.ZERO;
} else if(state == NumberState.EXPONENT) {
state = NumberState.EXP_SIGN;
} else if(state != NumberState.DIGITS
&& state != NumberState.FRACTION
&& state != NumberState.EXP_SIGN) {
throw new MalformedJsonException("Wrong number format at position " + position);
}
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(state == NumberState.NONE
|| state == NumberState.MINUS) {
state = NumberState.DIGITS;
}
if(state == NumberState.EXPONENT) {
state = NumberState.EXP_SIGN;
}
break;
case '-':
if(state == NumberState.NONE) {
state = NumberState.MINUS;
} else if(state == NumberState.EXPONENT) {
state = NumberState.EXP_SIGN;
} else {
throw new MalformedJsonException("Wrong number format at position " + position);
}
break;
case '+':
if(state != NumberState.EXPONENT) {
throw new MalformedJsonException("Wrong number format at position " + position);
}
state = NumberState.EXP_SIGN;
break;
case '.':
if(state != NumberState.ZERO
&& state != NumberState.DIGITS) {
throw new MalformedJsonException("Wrong number format at position " + position);
}
state = NumberState.FRACTION;
break;
case 'e':
case 'E':
if(state != NumberState.NONE
&& state != NumberState.ZERO
&& state != NumberState.DIGITS
&& state != NumberState.FRACTION) {
throw new MalformedJsonException("Wrong number format at position " + position);
}
state = NumberState.EXPONENT;
break;
case '}':
case ']':
case ':':
case ',':
case ' ':
case '\t':
case '\f':
case '\r':
case '\n':
state = NumberState.DONE;
position--; // this char should be consumed by outer call
break;
default:
throw new MalformedJsonException("Wrong number format at position " + position);
}
if(position >= data.length - 1) {
if(state == NumberState.DIGITS
|| state == NumberState.ZERO
|| state == NumberState.FRACTION
|| state == NumberState.EXP_SIGN) {
state = NumberState.DONE;
}
if(state != NumberState.DONE) {
throw new MalformedJsonException("Wrong number format at position " + position);
}
}
position++;
}
return new JsonToken(TokenType.NUMBER, startPosition, position);
}