in src/com/amazon/ion/impl/IonReaderTextRawTokensX.java [1529:1637]
protected IonType load_number(StringBuilder sb) throws IOException
{
boolean has_sign = false;
int t, c;
// this reads int, float, decimal and timestamp strings
// anything staring with a +, a - or a digit
//case '0': case '1': case '2': case '3': case '4':
//case '5': case '6': case '7': case '8': case '9':
//case '-': case '+':
//start_pos = _stream.getPosition();
c = read_char();
has_sign = ((c == '-') || (c == '+'));
if (has_sign) {
// if there is a sign character, we just consume it
// here and get whatever is next in line
sb.append((char)c);
c = read_char();
}
// first leading digit - to look for hex and
// to make sure that there is at least 1 digit (or
// this isn't really a number
if (!IonTokenConstsX.isDigit(c)) {
// if it's not a digit, this isn't a number
// the only non-digit it could have been was a
// sign character, and we'll have read past that
// by now
// TODO this will be a confusing error message,
// but I can't figure out when it will be reached.
bad_token(c);
}
// the first digit is a special case
boolean starts_with_zero = (c == '0');
if (starts_with_zero) {
// if it's a leading 0 check for a hex value
int c2 = read_char();
if (Radix.HEX.isPrefix(c2)) {
sb.append((char)c);
c = loadRadixValue(sb, has_sign, c2, Radix.HEX);
return load_finish_number(sb, c, IonTokenConstsX.TOKEN_HEX);
} else if (Radix.BINARY.isPrefix(c2)) {
sb.append((char) c);
c = loadRadixValue(sb, has_sign, c2, Radix.BINARY);
return load_finish_number(sb, c, IonTokenConstsX.TOKEN_BINARY);
}
// not a next value, back up and try again
unread_char(c2);
}
// remaining (after the first, c is the first) leading digits
c = load_digits(sb, c);
if (c == '-' || c == 'T') {
// this better be a timestamp and it starts with a 4 digit
// year followed by a dash and no leading sign
if (has_sign) {
error("Numeric value followed by invalid character: "
+ sb + (char)c);
}
int len = sb.length();
if (len != 4) {
error("Numeric value followed by invalid character: "
+ sb + (char)c);
}
IonType tt = load_timestamp(sb, c);
return tt;
}
if (starts_with_zero) {
// Ion doesn't allow leading zeros, so make sure our buffer only
// has one character.
int len = sb.length();
if (has_sign) {
len--; // we don't count the sign
}
if (len != 1) {
error("Invalid leading zero in number: " + sb);
}
}
if (c == '.') {
// so if it's a float of some sort
// mark it as at least a DECIMAL
// and read the "fraction" digits
sb.append((char)c);
c = read_char();
c = load_digits(sb, c);
t = IonTokenConstsX.TOKEN_DECIMAL;
}
else {
t = IonTokenConstsX.TOKEN_INT;
}
// see if we have an exponential as in 2d+3
if (c == 'e' || c == 'E') {
t = IonTokenConstsX.TOKEN_FLOAT;
sb.append((char)c);
c = load_exponent(sb); // the unused lookahead char
}
else if (c == 'd' || c == 'D') {
t = IonTokenConstsX.TOKEN_DECIMAL;
sb.append((char)c);
c = load_exponent(sb);
}
return load_finish_number(sb, c, t);
}