in src/com/amazon/ion/impl/IonReaderTextSystemX.java [205:430]
private final void load_scalar_value() throws IOException {
// make sure we're trying to load a scalar value here
switch(_value_type) {
case NULL:
_v.setValueToNull(_null_type);
_v.setAuthoritativeType(AS_TYPE.null_value);
return;
case BOOL:
case INT:
case FLOAT:
case DECIMAL:
case TIMESTAMP:
case SYMBOL:
case STRING:
break;
default:
return;
}
StringBuilder cs = token_contents_load(_scanner.getToken());
int token_type = _scanner.getToken();
if (_value_type == IonType.DECIMAL) {
// we do this here (instead of in the case below
// so that we can modify the value while it's not
// a string, but still in the StringBuilder
for (int ii=0; ii<cs.length(); ii++) {
int c = cs.charAt(ii);
if (c == 'd' || c == 'D') {
cs.setCharAt(ii, 'e');
break;
}
}
} else if (token_type == IonTokenConstsX.TOKEN_HEX || token_type == IonTokenConstsX.TOKEN_BINARY) {
boolean isNegative = (cs.charAt(0) == '-');
// prefix = is_negative ? "-0x" : "0x";
int pos = isNegative ? 1 : 0;
char caseChar = token_type == IonTokenConstsX.TOKEN_HEX ? 'x' : 'b';
if (cs.length() <= (isNegative ? 3 : 2) || Character.toLowerCase(cs.charAt(pos + 1)) != caseChar) {
parse_error("Invalid " + (caseChar == 'x' ? "hexadecimal" : "binary") + " int value.");
}
cs.deleteCharAt(pos);
cs.deleteCharAt(pos);
}
int len = cs.length();
String s = cs.toString();
clear_current_value_buffer();
switch (token_type) {
case IonTokenConstsX.TOKEN_UNKNOWN_NUMERIC:
switch (_value_type) {
case INT:
if (Radix.DECIMAL.isInt(s, len)) {
_v.setValue(Integer.parseInt(s));
}
else if (Radix.DECIMAL.isLong(s, len)) {
_v.setValue(Long.parseLong(s));
}
else {
_v.setValue(new BigInteger(s));
}
break;
case DECIMAL:
// note that the string was modified above when it was a charsequence
try {
_v.setValue(Decimal.valueOf(s));
}
catch (NumberFormatException e) {
parse_error(e);
}
break;
case FLOAT:
try {
_v.setValue(Double.parseDouble(s));
}
catch (NumberFormatException e) {
parse_error(e);
}
break;
case TIMESTAMP:
_v.setValue(Timestamp.valueOf(s));
break;
default:
String message = "unexpected prefectched value type "
+ getType().toString()
+ " encountered handling an unquoted symbol";
parse_error(message);
}
break;
case IonTokenConstsX.TOKEN_INT:
if (Radix.DECIMAL.isInt(s, len)) {
_v.setValue(Integer.parseInt(s));
}
else if (Radix.DECIMAL.isLong(s, len)) {
_v.setValue(Long.parseLong(s));
}
else {
_v.setValue(new BigInteger(s));
}
break;
case IonTokenConstsX.TOKEN_BINARY:
if (Radix.BINARY.isInt(s, len)) {
_v.setValue(Integer.parseInt(s, 2));
}
else if (Radix.BINARY.isLong(s, len)) {
_v.setValue(Long.parseLong(s, 2));
}
else {
_v.setValue(new BigInteger(s, 2));
}
break;
case IonTokenConstsX.TOKEN_HEX:
if (Radix.HEX.isInt(s, len)) {
int v_int = Integer.parseInt(s, 16);
_v.setValue(v_int);
}
else if (Radix.HEX.isLong(s, len)) {
long v_long = Long.parseLong(s, 16);
_v.setValue(v_long);
}
else {
BigInteger v_big_int = new BigInteger(s, 16);
_v.setValue(v_big_int);
}
break;
case IonTokenConstsX.TOKEN_DECIMAL:
try {
_v.setValue(Decimal.valueOf(s));
}
catch (NumberFormatException e) {
parse_error(e);
}
break;
case IonTokenConstsX.TOKEN_FLOAT:
try {
_v.setValue(Double.parseDouble(s));
}
catch (NumberFormatException e) {
parse_error(e);
}
break;
case IonTokenConstsX.TOKEN_TIMESTAMP:
Timestamp t = null;
try {
t = Timestamp.valueOf(s);
}
catch (IllegalArgumentException e) {
parse_error(e);
}
_v.setValue(t);
break;
case IonTokenConstsX.TOKEN_SYMBOL_IDENTIFIER:
// this includes the various value keywords like true
// and nan, in addition to "normal" unquoted symbols
// we check to make sure it's not null first
// since it could be null.symbol (which would
// have the getType() of SYMBOL and would confuse
// us as to what the saved type is)
if (isNullValue()) {
// the raw parser set _null_type when it
// detected the unquoted symbol null in the
// input (which is what isNullValue looks at)
_v.setValueToNull(_null_type);
}
else {
switch(getType()) {
case SYMBOL:
// TODO this is catching SIDs too, using wrong text.
_v.setValue(s);
break;
case FLOAT:
switch (_value_keyword) {
case IonTokenConstsX.KEYWORD_NAN:
_v.setValue(Double.NaN);
break;
default:
String message = "unexpected keyword "
+ s
+ " identified as a FLOAT";
parse_error(message);
}
break;
case BOOL:
switch (_value_keyword) {
case IonTokenConstsX.KEYWORD_TRUE:
_v.setValue(true);
break;
case IonTokenConstsX.KEYWORD_FALSE:
_v.setValue(false);
break;
default:
String message = "unexpected keyword "
+ s
+ " identified as a BOOL";
parse_error(message);
}
break;
default:
String message = "unexpected prefectched value type "
+ getType().toString()
+ " encountered handling an unquoted symbol";
parse_error(message);
}
}
break;
case IonTokenConstsX.TOKEN_SYMBOL_QUOTED:
case IonTokenConstsX.TOKEN_SYMBOL_OPERATOR:
case IonTokenConstsX.TOKEN_STRING_DOUBLE_QUOTE:
_v.setValue(s);
break;
case IonTokenConstsX.TOKEN_STRING_TRIPLE_QUOTE:
// long strings (triple quoted strings) are never
// finished by the raw parser. At most it reads
// the first triple quoted string.
_v.setValue(s);
break;
default:
parse_error("scalar token "+IonTokenConstsX.getTokenName(_scanner.getToken())+"isn't a recognized type");
}
}