FromStringWithRadixToNumberDeserializer.java
package tools.jackson.databind.deser.std;
import java.math.BigInteger;
import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.util.ClassUtil;
/**
* Deserializer used for a string that represents a number in specific radix (base).
*
* @since 3.1
*/
public class FromStringWithRadixToNumberDeserializer
extends StdScalarDeserializer<Number>
{
private final int radix;
public FromStringWithRadixToNumberDeserializer(StdScalarDeserializer<?> src, int radix) {
super(src);
this.radix = radix;
}
@Override
public Number deserialize(JsonParser p, DeserializationContext ctxt) {
Class<?> handledType = handledType();
// Should we allow (Integer) numbers? At least with "lenient" format settings?
if (!p.hasToken(JsonToken.VALUE_STRING)) {
ctxt.reportInputMismatch(handledType,
"Need String when deserializing a value using `FromStringWithRadixToNumberDeserializer` (radix: %d)",
radix);
}
String text = p.getString();
// First, DoS check
p.streamReadConstraints().validateIntegerLength(text.length());
try {
if (handledType.equals(BigInteger.class)) {
return new BigInteger(text, radix);
}
// Map from wrappers to primitive
Class<?> primitiveType = ClassUtil.primitiveType(handledType);
// start with more likely types
if (primitiveType == long.class) {
return Long.parseLong(text, radix);
}
if (primitiveType == int.class) {
return Integer.parseInt(text, radix);
}
if (primitiveType == short.class) {
return Short.parseShort(text, radix);
}
if (primitiveType == byte.class) {
return Byte.parseByte(text, radix);
}
} catch (IllegalArgumentException iae) {
return (Number) ctxt.handleWeirdStringValue(handledType, text,
"not a valid representation of %s value with radix %d",
ClassUtil.nameOf(handledType), radix);
}
// Is this really true?
return ctxt.reportInputMismatch(handledType,
"Trying to deserialize a non-whole number with `NumberToStringWithRadixSerializer`");
}
}