gson-comments/gson/src/main/java/com/google/gson/ToNumberPolicy.java

106 lines
3.7 KiB
Java

/*
* Copyright (C) 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gson;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.internal.NumberLimits;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.math.BigDecimal;
/**
* An enumeration that defines two standard number reading strategies and a couple of strategies to
* overcome some historical Gson limitations while deserializing numbers as {@link Object} and
* {@link Number}.
*
* @see ToNumberStrategy
* @since 2.8.9
*/
public enum ToNumberPolicy implements ToNumberStrategy {
/**
* Using this policy will ensure that numbers will be read as {@link Double} values. This is the
* default strategy used during deserialization of numbers as {@link Object}.
*/
DOUBLE {
@Override
public Double readNumber(JsonReader in) throws IOException {
return in.nextDouble();
}
},
/**
* Using this policy will ensure that numbers will be read as a lazily parsed number backed by a
* string. This is the default strategy used during deserialization of numbers as {@link Number}.
*/
LAZILY_PARSED_NUMBER {
@Override
public Number readNumber(JsonReader in) throws IOException {
return new LazilyParsedNumber(in.nextString());
}
},
/**
* Using this policy will ensure that numbers will be read as {@link Long} or {@link Double}
* values depending on how JSON numbers are represented: {@code Long} if the JSON number can be
* parsed as a {@code Long} value, or otherwise {@code Double} if it can be parsed as a {@code
* Double} value. If the parsed double-precision number results in a positive or negative infinity
* ({@link Double#isInfinite()}) or a NaN ({@link Double#isNaN()}) value and the {@code
* JsonReader} is not {@link JsonReader#isLenient() lenient}, a {@link MalformedJsonException} is
* thrown.
*/
LONG_OR_DOUBLE {
@Override
public Number readNumber(JsonReader in) throws IOException, JsonParseException {
String value = in.nextString();
try {
return Long.parseLong(value);
} catch (NumberFormatException longE) {
try {
Double d = Double.valueOf(value);
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) {
throw new MalformedJsonException(
"JSON forbids NaN and infinities: " + d + "; at path " + in.getPreviousPath());
}
return d;
} catch (NumberFormatException doubleE) {
throw new JsonParseException(
"Cannot parse " + value + "; at path " + in.getPreviousPath(), doubleE);
}
}
}
},
/**
* Using this policy will ensure that numbers will be read as numbers of arbitrary length using
* {@link BigDecimal}.
*/
BIG_DECIMAL {
@Override
public BigDecimal readNumber(JsonReader in) throws IOException {
String value = in.nextString();
try {
return NumberLimits.parseBigDecimal(value);
} catch (NumberFormatException e) {
throw new JsonParseException(
"Cannot parse " + value + "; at path " + in.getPreviousPath(), e);
}
}
}
}