diff --git a/src/main/java/com/fasterxml/jackson/core/JsonParser.java b/src/main/java/com/fasterxml/jackson/core/JsonParser.java index 9dc91beccb..3a82b22f51 100644 --- a/src/main/java/com/fasterxml/jackson/core/JsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/JsonParser.java @@ -1634,3 +1634,4 @@ protected final StreamReadException _constructReadException(String msg, Throwabl return new StreamReadException(this, msg, t); } } + diff --git a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java index 4363e2b8a5..1d1d5939e6 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java @@ -959,3 +959,4 @@ protected ContentReference _contentReference() { return ContentReference.unknown(); } } + diff --git a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java index ed01b858e2..0ea7c0ca22 100644 --- a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java +++ b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java @@ -1,5 +1,8 @@ package com.fasterxml.jackson.core.io; +import com.fasterxml.jackson.core.io.doubleparser.FastDoubleParser; +import com.fasterxml.jackson.core.io.doubleparser.FastFloatParser; + import java.math.BigDecimal; public final class NumberInput @@ -226,7 +229,9 @@ public static int parseAsInt(String s, int def) // if other symbols, parse as Double, coerce if (c > '9' || c < '0') { try { - return (int) parseDouble(s); + //useFastParser=true is used because there is a lot less risk that small changes in result will have an affect + //and performance benefit is useful + return (int) parseDouble(s, true); } catch (NumberFormatException e) { return def; } @@ -263,7 +268,9 @@ public static long parseAsLong(String s, long def) // if other symbols, parse as Double, coerce if (c > '9' || c < '0') { try { - return (long) parseDouble(s); + //useFastParser=true is used because there is a lot less risk that small changes in result will have an affect + //and performance benefit is useful + return (long) parseDouble(s, true); } catch (NumberFormatException e) { return def; } @@ -274,8 +281,26 @@ public static long parseAsLong(String s, long def) } catch (NumberFormatException e) { } return def; } - - public static double parseAsDouble(String s, double def) + + /** + * @param s a string representing a number to parse + * @param def the default to return if `s` is not a parseable number + * @return closest matching double (or `def` if there is an issue with `s`) where useFastParser=false + * @see #parseAsDouble(String, double, boolean) + */ + public static double parseAsDouble(final String s, final double def) + { + return parseAsDouble(s, def, false); + } + + /** + * @param s a string representing a number to parse + * @param def the default to return if `s` is not a parseable number + * @param useFastParser whether to use {@link com.fasterxml.jackson.core.io.doubleparser} + * @return closest matching double (or `def` if there is an issue with `s`) + * @since 2.14 + */ + public static double parseAsDouble(String s, final double def, final boolean useFastParser) { if (s == null) { return def; } s = s.trim(); @@ -284,23 +309,52 @@ public static double parseAsDouble(String s, double def) return def; } try { - return parseDouble(s); + return parseDouble(s, useFastParser); } catch (NumberFormatException e) { } return def; } - public static double parseDouble(String s) throws NumberFormatException { - return Double.parseDouble(s); + /** + * @param s a string representing a number to parse + * @return closest matching double + * @throws NumberFormatException if string cannot be represented by a double where useFastParser=false + * @see #parseDouble(String, boolean) + */ + public static double parseDouble(final String s) throws NumberFormatException { + return parseDouble(s, false); + } + + /** + * @param s a string representing a number to parse + * @param useFastParser whether to use {@link com.fasterxml.jackson.core.io.doubleparser} + * @return closest matching double + * @throws NumberFormatException if string cannot be represented by a double + * @since v2.14 + */ + public static double parseDouble(final String s, final boolean useFastParser) throws NumberFormatException { + return useFastParser ? FastDoubleParser.parseDouble(s) : Double.parseDouble(s); + } + + /** + * @param s a string representing a number to parse + * @return closest matching float + * @throws NumberFormatException if string cannot be represented by a float where useFastParser=false + * @see #parseFloat(String, boolean) + * @since v2.14 + */ + public static float parseFloat(final String s) throws NumberFormatException { + return parseFloat(s, false); } /** * @param s a string representing a number to parse + * @param useFastParser whether to use {@link com.fasterxml.jackson.core.io.doubleparser} * @return closest matching float * @throws NumberFormatException if string cannot be represented by a float * @since v2.14 */ - public static float parseFloat(String s) throws NumberFormatException { - return Float.parseFloat(s); + public static float parseFloat(final String s, final boolean useFastParser) throws NumberFormatException { + return useFastParser ? FastFloatParser.parseFloat(s) : Float.parseFloat(s); } public static BigDecimal parseBigDecimal(String s) throws NumberFormatException { diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonParserBase.java b/src/main/java/com/fasterxml/jackson/core/json/JsonParserBase.java index 768ec8c32b..22b99532a7 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/JsonParserBase.java +++ b/src/main/java/com/fasterxml/jackson/core/json/JsonParserBase.java @@ -241,11 +241,11 @@ private void _parseSlowFloat(int expType) throws JacksonException _numberBigDecimal = _textBuffer.contentsAsDecimal(); _numTypesValid = NR_BIGDECIMAL; } else if (expType == NR_FLOAT) { - _numberFloat = _textBuffer.contentsAsFloat(); + _numberFloat = _textBuffer.contentsAsFloat(isEnabled(JsonReadFeature.USE_FAST_DOUBLE_PARSER)); _numTypesValid = NR_FLOAT; } else { // Otherwise double has to do - _numberDouble = _textBuffer.contentsAsDouble(); + _numberDouble = _textBuffer.contentsAsDouble(isEnabled(JsonReadFeature.USE_FAST_DOUBLE_PARSER)); _numTypesValid = NR_DOUBLE; } } catch (NumberFormatException nex) { @@ -276,7 +276,7 @@ private void _parseSlowInt(int expType) throws JacksonException _reportTooLongIntegral(expType, numStr); } if ((expType == NR_DOUBLE) || (expType == NR_FLOAT)) { - _numberDouble = NumberInput.parseDouble(numStr); + _numberDouble = NumberInput.parseDouble(numStr, isEnabled(JsonReadFeature.USE_FAST_DOUBLE_PARSER)); _numTypesValid = NR_DOUBLE; } else { // nope, need the heavy guns... (rare case) diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java b/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java index 743c181acf..4b8c3d94d2 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java +++ b/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java @@ -175,6 +175,17 @@ public enum JsonReadFeature * feature, and as such disabled by default. */ ALLOW_TRAILING_COMMA(false), + + /** + * Feature that determines whether we use the built-in {@link Double#parseDouble(String)} code to parse + * doubles or if we use {@link com.fasterxml.jackson.core.io.doubleparser} + * instead. + *
+ * This setting is disabled by default. + * + * @since 2.14 + */ + USE_FAST_DOUBLE_PARSER(false) ; final private boolean _defaultState; diff --git a/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java b/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java index 532cafdac6..a597bbc0bc 100644 --- a/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java +++ b/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java @@ -504,9 +504,25 @@ public BigDecimal contentsAsDecimal() throws NumberFormatException * @return Buffered text value parsed as a {@link Double}, if possible * * @throws NumberFormatException if contents are not a valid Java number + * @deprecated use {@link #contentsAsDouble(boolean)} */ + @Deprecated public double contentsAsDouble() throws NumberFormatException { - return NumberInput.parseDouble(contentsAsString()); + return contentsAsDouble(false); + } + + /** + * Convenience method for converting contents of the buffer + * into a Double value. + * + * @param useFastParser whether to use {@link com.fasterxml.jackson.core.io.doubleparser} + * @return Buffered text value parsed as a {@link Double}, if possible + * + * @throws NumberFormatException if contents are not a valid Java number + * @since 2.14 + */ + public double contentsAsDouble(final boolean useFastParser) throws NumberFormatException { + return NumberInput.parseDouble(contentsAsString(), useFastParser); } /** @@ -517,9 +533,25 @@ public double contentsAsDouble() throws NumberFormatException { * * @throws NumberFormatException if contents are not a valid Java number * @since 2.14 + * @deprecated use {@link #contentsAsFloat(boolean)} */ + @Deprecated public float contentsAsFloat() throws NumberFormatException { - return NumberInput.parseFloat(contentsAsString()); + return contentsAsFloat(false); + } + + /** + * Convenience method for converting contents of the buffer + * into a Float value. + * + * @param useFastParser whether to use {@link com.fasterxml.jackson.core.io.doubleparser} + * @return Buffered text value parsed as a {@link Float}, if possible + * + * @throws NumberFormatException if contents are not a valid Java number + * @since 2.14 + */ + public float contentsAsFloat(final boolean useFastParser) throws NumberFormatException { + return NumberInput.parseFloat(contentsAsString(), useFastParser); } /** diff --git a/src/test/java/com/fasterxml/jackson/core/io/TestNumberInput.java b/src/test/java/com/fasterxml/jackson/core/io/TestNumberInput.java index 1035ac6c8d..bf1f80c247 100644 --- a/src/test/java/com/fasterxml/jackson/core/io/TestNumberInput.java +++ b/src/test/java/com/fasterxml/jackson/core/io/TestNumberInput.java @@ -9,13 +9,20 @@ public void testNastySmallDouble() //prior to jackson v2.14, this value used to be returned as Double.MIN_VALUE final String nastySmallDouble = "2.2250738585072012e-308"; assertEquals(Double.parseDouble(nastySmallDouble), NumberInput.parseDouble(nastySmallDouble)); + assertEquals(Double.parseDouble(nastySmallDouble), NumberInput.parseDouble(nastySmallDouble, true)); } public void testParseFloat() { final String exampleFloat = "1.199999988079071"; assertEquals(1.1999999f, NumberInput.parseFloat(exampleFloat)); + assertEquals(1.1999999f, NumberInput.parseFloat(exampleFloat, true)); assertEquals(1.2f, (float)NumberInput.parseDouble(exampleFloat)); + assertEquals(1.2f, (float)NumberInput.parseDouble(exampleFloat, true)); + + final String exampleFloat2 = "7.006492321624086e-46"; + assertEquals("1.4E-45", Float.toString(NumberInput.parseFloat(exampleFloat2))); + assertEquals("1.4E-45", Float.toString(NumberInput.parseFloat(exampleFloat2, true))); } } diff --git a/src/test/java/com/fasterxml/jackson/core/read/FastParserNonStandardNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/FastParserNonStandardNumberParsingTest.java new file mode 100644 index 0000000000..0c8817013a --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/core/read/FastParserNonStandardNumberParsingTest.java @@ -0,0 +1,17 @@ +package com.fasterxml.jackson.core.read; + +import com.fasterxml.jackson.core.json.JsonFactory; +import com.fasterxml.jackson.core.json.JsonReadFeature; + +public class FastParserNonStandardNumberParsingTest extends NonStandardNumberParsingTest { + private final JsonFactory fastFactory = + JsonFactory.builder() + .enable(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS) + .enable(JsonReadFeature.USE_FAST_DOUBLE_PARSER) + .build(); + + @Override + protected JsonFactory jsonFactory() { + return fastFactory; + } +} diff --git a/src/test/java/com/fasterxml/jackson/core/read/FastParserNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/FastParserNumberParsingTest.java new file mode 100644 index 0000000000..96859d3dc5 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/core/read/FastParserNumberParsingTest.java @@ -0,0 +1,17 @@ +package com.fasterxml.jackson.core.read; + +import com.fasterxml.jackson.core.json.JsonFactory; +import com.fasterxml.jackson.core.json.JsonReadFeature; + +public class FastParserNumberParsingTest extends NumberParsingTest { + + private final JsonFactory fastFactory = + JsonFactory.builder() + .enable(JsonReadFeature.USE_FAST_DOUBLE_PARSER) + .build(); + + @Override + protected JsonFactory jsonFactory() { + return fastFactory; + } +} diff --git a/src/test/java/com/fasterxml/jackson/core/read/FloatParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/FloatParsingTest.java index 6d2762b038..cf1857ac6d 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/FloatParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/FloatParsingTest.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.TokenStreamFactory; +import com.fasterxml.jackson.core.json.JsonFactory; +import com.fasterxml.jackson.core.json.JsonReadFeature; // for [core#755] public class FloatParsingTest extends BaseTest @@ -12,22 +14,41 @@ public class FloatParsingTest extends BaseTest public void testFloatArrayViaInputStream() throws Exception { - _testFloatArray(MODE_INPUT_STREAM); - _testFloatArray(MODE_INPUT_STREAM_THROTTLED); + _testFloatArray(MODE_INPUT_STREAM, false); + _testFloatArray(MODE_INPUT_STREAM_THROTTLED, false); + } + + public void testFloatArrayViaInputStreamWithFastParser() throws Exception + { + _testFloatArray(MODE_INPUT_STREAM, true); + _testFloatArray(MODE_INPUT_STREAM_THROTTLED, true); } public void testFloatArrayViaReader() throws Exception { - _testFloatArray(MODE_READER); + _testFloatArray(MODE_READER, false); + } + + public void testFloatArrayViaReaderWithFastParser() throws Exception { + _testFloatArray(MODE_READER, true); } public void testFloatArrayViaDataInput() throws Exception { - _testFloatArray(MODE_DATA_INPUT); + _testFloatArray(MODE_DATA_INPUT, false); + } + + public void testFloatArrayViaDataInputWithFasrtParser() throws Exception { + _testFloatArray(MODE_DATA_INPUT, true); } - private void _testFloatArray(int mode) throws Exception + private void _testFloatArray(int mode, boolean useFastParser) throws Exception { // construct new instance to reduce buffer recycling etc: - TokenStreamFactory jsonF = newStreamFactory(); + final TokenStreamFactory jsonF ; + if (useFastParser) { + jsonF = JsonFactory.builder().enable(JsonReadFeature.USE_FAST_DOUBLE_PARSER).build(); + } else { + jsonF = newStreamFactory(); + } JsonParser p = createParser(jsonF, mode, FLOATS_DOC); diff --git a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java index ffe7f9d6b9..34d4a5c82b 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java @@ -6,12 +6,16 @@ import com.fasterxml.jackson.core.json.JsonReadFeature; public class NonStandardNumberParsingTest - extends com.fasterxml.jackson.core.BaseTest + extends com.fasterxml.jackson.core.BaseTest { private final JsonFactory JSON_F = JsonFactory.builder() .enable(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS) .build(); + protected JsonFactory jsonFactory() { + return JSON_F; + } + /** * The format ".NNN" (as opposed to "0.NNN") is not valid JSON, so this should fail */ @@ -29,16 +33,16 @@ public void testLeadingDotInDecimal() { } public void testLeadingDotInDecimalAllowedAsync() { - _testLeadingDotInDecimalAllowed(JSON_F, MODE_DATA_INPUT); + _testLeadingDotInDecimalAllowed(jsonFactory(), MODE_DATA_INPUT); } public void testLeadingDotInDecimalAllowedBytes() { - _testLeadingDotInDecimalAllowed(JSON_F, MODE_INPUT_STREAM); - _testLeadingDotInDecimalAllowed(JSON_F, MODE_INPUT_STREAM_THROTTLED); + _testLeadingDotInDecimalAllowed(jsonFactory(), MODE_INPUT_STREAM); + _testLeadingDotInDecimalAllowed(jsonFactory(), MODE_INPUT_STREAM_THROTTLED); } public void testLeadingDotInDecimalAllowedReader() { - _testLeadingDotInDecimalAllowed(JSON_F, MODE_READER); + _testLeadingDotInDecimalAllowed(jsonFactory(), MODE_READER); } private void _testLeadingDotInDecimalAllowed(JsonFactory f, int mode) diff --git a/src/test/java/com/fasterxml/jackson/core/read/NumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/NumberParsingTest.java index be8dabb045..4b80552bcf 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/NumberParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/NumberParsingTest.java @@ -19,10 +19,14 @@ */ @SuppressWarnings("resource") public class NumberParsingTest - extends com.fasterxml.jackson.core.BaseTest + extends com.fasterxml.jackson.core.BaseTest { private final TokenStreamFactory FACTORY = sharedStreamFactory(); + protected JsonFactory jsonFactory() { + return sharedStreamFactory(); + } + /* /********************************************************************** /* Tests, Boolean @@ -145,7 +149,7 @@ public void testIntRange() assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(JsonParser.NumberType.INT, p.getNumberType()); assertEquals(Integer.MAX_VALUE, p.getIntValue()); - + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(JsonParser.NumberType.INT, p.getNumberType()); assertEquals(Integer.MIN_VALUE, p.getIntValue()); @@ -207,7 +211,7 @@ public void testSimpleLong() private void _testSimpleLong(int mode) { long EXP_L = 12345678907L; - + JsonParser p = createParser(mode, "[ "+EXP_L+" ]"); assertToken(JsonToken.START_ARRAY, p.nextToken()); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); @@ -216,7 +220,7 @@ private void _testSimpleLong(int mode) assertEquals(""+EXP_L, p.getText()); assertEquals(EXP_L, p.getLongValue()); - // Should get an exception if trying to convert to int + // Should get an exception if trying to convert to int try { p.getIntValue(); } catch (InputCoercionException e) { @@ -240,7 +244,7 @@ public void testLongRange() assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(JsonParser.NumberType.LONG, p.getNumberType()); assertEquals(Long.MAX_VALUE, p.getLongValue()); - + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(JsonParser.NumberType.LONG, p.getNumberType()); assertEquals(Long.MIN_VALUE, p.getLongValue()); @@ -253,8 +257,8 @@ public void testLongRange() assertEquals(JsonParser.NumberType.LONG, p.getNumberType()); assertEquals(belowMinInt, p.getLongValue()); - - assertToken(JsonToken.END_ARRAY, p.nextToken()); + + assertToken(JsonToken.END_ARRAY, p.nextToken()); p.close(); } } @@ -301,13 +305,13 @@ public void testLongBoundsChecks() cbuf = aboveMaxLong.toCharArray(); assertFalse(NumberInput.inLongRange(cbuf, 0, cbuf.length, false)); } - + /* /********************************************************************** /* Tests, BigXxx /********************************************************************** */ - + public void testBigDecimalRange() { for (int mode : ALL_MODES) { @@ -325,7 +329,7 @@ public void testBigDecimalRange() assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(JsonParser.NumberType.BIG_INTEGER, p.getNumberType()); assertEquals(big, p.getBigIntegerValue()); - assertToken(JsonToken.END_ARRAY, p.nextToken()); + assertToken(JsonToken.END_ARRAY, p.nextToken()); p.close(); } } @@ -355,19 +359,19 @@ public void testBigNumbers() /* Tests, floating point (basic) /********************************************************************** */ - + public void testSimpleDouble() { final String[] INPUTS = new String[] { - "1234.00", "2.1101567E-16", "1.0e5", "0.0", "1.0", "-1.0", - "-0.5", "-12.9", "-999.0", - "2.5e+5", "9e4", "-12e-3", "0.25", + "1234.00", "2.1101567E-16", "1.0e5", "0.0", "1.0", "-1.0", + "-0.5", "-12.9", "-999.0", + "2.5e+5", "9e4", "-12e-3", "0.25", }; for (int mode : ALL_MODES) { for (int i = 0; i < INPUTS.length; ++i) { // First in array - + String STR = INPUTS[i]; double EXP_D = Double.parseDouble(STR); String DOC = "["+STR+"]"; @@ -393,7 +397,7 @@ public void testSimpleDouble() } catch (Exception e) { throw new RuntimeException("Failed to parse input '"+STR+"' (parser of type "+p.getClass().getSimpleName()+")", e); } - + assertToken(JsonToken.VALUE_NUMBER_FLOAT, t); assertEquals(STR, p.getText()); if (mode != MODE_DATA_INPUT) { @@ -408,16 +412,16 @@ public void testFloatBoundary146Chars() { final char[] arr = new char[50005]; for(int i = 500; i != 9000; ++i) { - java.util.Arrays.fill(arr, 0, i, ' '); - arr[i] = '-'; - arr[i + 1] = '1'; - arr[i + 2] = 'e'; - arr[i + 3] = '-'; - arr[i + 4] = '1'; - CharArrayReader r = new CharArrayReader(arr, 0, i+5); - JsonParser p = FACTORY.createParser(ObjectReadContext.empty(), r); - assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); - p.close(); + java.util.Arrays.fill(arr, 0, i, ' '); + arr[i] = '-'; + arr[i + 1] = '1'; + arr[i + 2] = 'e'; + arr[i + 3] = '-'; + arr[i + 4] = '1'; + CharArrayReader r = new CharArrayReader(arr, 0, i+5); + JsonParser p = jsonFactory().createParser(ObjectReadContext.empty(), r); + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); + p.close(); } } @@ -432,7 +436,7 @@ public void testFloatBoundary146Bytes() arr[i + 3] = '-'; arr[i + 4] = '1'; ByteArrayInputStream in = new ByteArrayInputStream(arr, 0, i+5); - JsonParser p = FACTORY.createParser(ObjectReadContext.empty(), in); + JsonParser p = jsonFactory().createParser(ObjectReadContext.empty(), in); assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); p.close(); } @@ -463,28 +467,28 @@ public void testBigBigDecimalsDataInput() throws Exception private void _testBigBigDecimals(int mode) throws Exception { final String BASE_FRACTION = - "01610253934481930774151441507943554511027782188707463024288149352877602369090537" -+"80583522838238149455840874862907649203136651528841378405339370751798532555965157588" -+"51877960056849468879933122908090021571162427934915567330612627267701300492535817858" -+"36107216979078343419634586362681098115326893982589327952357032253344676618872460059" -+"52652865429180458503533715200184512956356092484787210672008123556320998027133021328" -+"04777044107393832707173313768807959788098545050700242134577863569636367439867566923" -+"33479277494056927358573496400831024501058434838492057410330673302052539013639792877" -+"76670882022964335417061758860066263335250076803973514053909274208258510365484745192" -+"39425298649420795296781692303253055152441850691276044546565109657012938963181532017" -+"97420631515930595954388119123373317973532146157980827838377034575940814574561703270" -+"54949003909864767732479812702835339599792873405133989441135669998398892907338968744" -+"39682249327621463735375868408190435590094166575473967368412983975580104741004390308" -+"45302302121462601506802738854576700366634229106405188353120298347642313881766673834" -+"60332729485083952142460470270121052469394888775064758246516888122459628160867190501" -+"92476878886543996441778751825677213412487177484703116405390741627076678284295993334" -+"23142914551517616580884277651528729927553693274406612634848943914370188078452131231" -+"17351787166509190240927234853143290940647041705485514683182501795615082930770566118" -+"77488417962195965319219352314664764649802231780262169742484818333055713291103286608" -+"64318433253572997833038335632174050981747563310524775762280529871176578487487324067" -+"90242862159403953039896125568657481354509805409457993946220531587293505986329150608" -+"18702520420240989908678141379300904169936776618861221839938283876222332124814830207" -+"073816864076428273177778788053613345444299361357958409716099682468768353446625063"; + "01610253934481930774151441507943554511027782188707463024288149352877602369090537" + +"80583522838238149455840874862907649203136651528841378405339370751798532555965157588" + +"51877960056849468879933122908090021571162427934915567330612627267701300492535817858" + +"36107216979078343419634586362681098115326893982589327952357032253344676618872460059" + +"52652865429180458503533715200184512956356092484787210672008123556320998027133021328" + +"04777044107393832707173313768807959788098545050700242134577863569636367439867566923" + +"33479277494056927358573496400831024501058434838492057410330673302052539013639792877" + +"76670882022964335417061758860066263335250076803973514053909274208258510365484745192" + +"39425298649420795296781692303253055152441850691276044546565109657012938963181532017" + +"97420631515930595954388119123373317973532146157980827838377034575940814574561703270" + +"54949003909864767732479812702835339599792873405133989441135669998398892907338968744" + +"39682249327621463735375868408190435590094166575473967368412983975580104741004390308" + +"45302302121462601506802738854576700366634229106405188353120298347642313881766673834" + +"60332729485083952142460470270121052469394888775064758246516888122459628160867190501" + +"92476878886543996441778751825677213412487177484703116405390741627076678284295993334" + +"23142914551517616580884277651528729927553693274406612634848943914370188078452131231" + +"17351787166509190240927234853143290940647041705485514683182501795615082930770566118" + +"77488417962195965319219352314664764649802231780262169742484818333055713291103286608" + +"64318433253572997833038335632174050981747563310524775762280529871176578487487324067" + +"90242862159403953039896125568657481354509805409457993946220531587293505986329150608" + +"18702520420240989908678141379300904169936776618861221839938283876222332124814830207" + +"073816864076428273177778788053613345444299361357958409716099682468768353446625063"; for (String asText : new String[] { "50."+BASE_FRACTION, @@ -518,7 +522,7 @@ public void testNumbers() _testNumbers(MODE_READER); _testNumbers(MODE_DATA_INPUT); } - + private void _testNumbers(int mode) { final String DOC = "[ -13, 8100200300, 13.5, 0.00010, -2.033 ]"; @@ -526,13 +530,13 @@ private void _testNumbers(int mode) JsonParser p = createParser(mode, DOC); assertToken(JsonToken.START_ARRAY, p.nextToken()); - + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(-13, p.getIntValue()); assertEquals(-13L, p.getLongValue()); assertEquals(-13., p.getDoubleValue()); assertEquals("-13", p.getText()); - + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(8100200300L, p.getLongValue()); // Should get exception for overflow: @@ -544,7 +548,7 @@ private void _testNumbers(int mode) } assertEquals(8100200300.0, p.getDoubleValue()); assertEquals("8100200300", p.getText()); - + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); assertEquals(13, p.getIntValue()); assertEquals(13L, p.getLongValue()); @@ -556,7 +560,7 @@ private void _testNumbers(int mode) assertEquals(0L, p.getLongValue()); assertEquals(0.00010, p.getDoubleValue()); assertEquals("0.00010", p.getText()); - + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); assertEquals(-2, p.getIntValue()); assertEquals(-2L, p.getLongValue()); @@ -568,7 +572,7 @@ private void _testNumbers(int mode) p.close(); } - + /** * Method that tries to test that number parsing works in cases where * input is split between buffer boundaries. @@ -613,7 +617,7 @@ public void testParsingOfLongerSequences() if (input == 0) { p = createParserUsingStream(DOC, "UTF-8"); } else { - p = FACTORY.createParser(ObjectReadContext.empty(), DOC); + p = jsonFactory().createParser(ObjectReadContext.empty(), DOC); } assertToken(JsonToken.START_ARRAY, p.nextToken()); @@ -641,13 +645,13 @@ public void testLongNumbers() _testLongNumbers(f, NUM, false); _testLongNumbers(f, NUM, true); } - + private void _testLongNumbers(JsonFactory f, String num, boolean useStream) { final String doc = "[ "+num+" ]"; JsonParser p = useStream ? f.createParser(ObjectReadContext.empty(), utf8Bytes(doc)) - : f.createParser(ObjectReadContext.empty(), doc); + : f.createParser(ObjectReadContext.empty(), doc); assertToken(JsonToken.START_ARRAY, p.nextToken()); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(num, p.getText()); @@ -672,8 +676,8 @@ public void testLongNumbers2() private void _testIssue160LongNumbers(JsonFactory f, String doc, boolean useStream) { JsonParser p = useStream - ? FACTORY.createParser(ObjectReadContext.empty(), utf8Bytes(doc)) - : FACTORY.createParser(ObjectReadContext.empty(), doc); + ? jsonFactory().createParser(ObjectReadContext.empty(), utf8Bytes(doc)) + : jsonFactory().createParser(ObjectReadContext.empty(), doc); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); BigInteger v = p.getBigIntegerValue(); assertNull(p.nextToken()); @@ -767,7 +771,7 @@ public void testInvalidIntAccess() { _testInvalidIntAccess(MODE_READER); _testInvalidIntAccess(MODE_DATA_INPUT); } - + private void _testInvalidIntAccess(int mode) { JsonParser p = createParser(mode, "[ \"abc\" ]"); @@ -788,7 +792,7 @@ public void testInvalidLongAccess() { _testInvalidLongAccess(MODE_READER); _testInvalidLongAccess(MODE_DATA_INPUT); } - + private void _testInvalidLongAccess(int mode) { JsonParser p = createParser(mode, "[ false ]"); @@ -816,11 +820,11 @@ public void testLongerFloatingPoint() // test out with both Reader and ByteArrayInputStream JsonParser p; - p = FACTORY.createParser(ObjectReadContext.empty(), new StringReader(DOC)); + p = jsonFactory().createParser(ObjectReadContext.empty(), new StringReader(DOC)); _testLongerFloat(p, DOC); p.close(); - - p = FACTORY.createParser(ObjectReadContext.empty(), + + p = jsonFactory().createParser(ObjectReadContext.empty(), new ByteArrayInputStream(utf8Bytes(DOC))); _testLongerFloat(p, DOC); p.close();