backing out recent changes to optLong, getLong. See #868

This commit is contained in:
Sean Leary
2024-02-24 13:07:51 -06:00
parent d36066cf82
commit 771c82c4eb
12 changed files with 175 additions and 580 deletions

View File

@@ -10,10 +10,6 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
import static org.json.NumberConversionUtil.potentialNumber;
import static org.json.NumberConversionUtil.stringToNumber;
/**
* This provides static methods to convert an XML text into a JSONObject, and to
* covert a JSONObject into an XML text.
@@ -499,6 +495,76 @@ public class XML {
return true;
}
/**
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
*/
private static Number stringToNumber(final String val) throws NumberFormatException {
char initial = val.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') {
// decimal representation
if (isDecimalNotation(val)) {
// Use a BigDecimal all the time so we keep the original
// representation. BigDecimal doesn't support -0.0, ensure we
// keep that by forcing a decimal.
try {
BigDecimal bd = new BigDecimal(val);
if(initial == '-' && BigDecimal.ZERO.compareTo(bd)==0) {
return Double.valueOf(-0.0);
}
return bd;
} catch (NumberFormatException retryAsDouble) {
// this is to support "Hex Floats" like this: 0x1.0P-1074
try {
Double d = Double.valueOf(val);
if(d.isNaN() || d.isInfinite()) {
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
return d;
} catch (NumberFormatException ignore) {
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
}
}
// block items like 00 01 etc. Java number parsers treat these as Octal.
if(initial == '0' && val.length() > 1) {
char at1 = val.charAt(1);
if(at1 >= '0' && at1 <= '9') {
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
} else if (initial == '-' && val.length() > 2) {
char at1 = val.charAt(1);
char at2 = val.charAt(2);
if(at1 == '0' && at2 >= '0' && at2 <= '9') {
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
}
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
// BigInteger down conversion: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
// long lived.
BigInteger bi = new BigInteger(val);
if(bi.bitLength() <= 31){
return Integer.valueOf(bi.intValue());
}
if(bi.bitLength() <= 63){
return Long.valueOf(bi.longValue());
}
return bi;
}
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
/**
* direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support.
*/
private static boolean isDecimalNotation(final String val) {
return val.indexOf('.') > -1 || val.indexOf('e') > -1
|| val.indexOf('E') > -1 || "-0".equals(val);
}
/**
* This method tries to convert the given string value to the target object
@@ -543,7 +609,8 @@ public class XML {
* produced, then the value will just be a string.
*/
if (potentialNumber(string)) {
char initial = string.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') {
try {
return stringToNumber(string);
} catch (Exception ignore) {
@@ -552,11 +619,6 @@ public class XML {
return string;
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject. Some information may be lost in this transformation because
@@ -975,5 +1037,4 @@ public class XML {
}
return sb.toString();
}
}