From 148978c2766dd4252e79887871313930716d3950 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 25 Jun 2022 15:45:49 +0100 Subject: [PATCH 1/9] support fast parser option --- .../dataformat/csv/impl/CsvDecoder.java | 2 +- .../dataformat/csv/impl/NumberInput.java | 22 ++++++++++++++++--- .../dataformat/csv/impl/TextBuffer.java | 18 ++++++++++++--- .../jackson/dataformat/csv/FeaturesTest.java | 12 ++++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java index 36c547f20..a877d24a5 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java @@ -1228,7 +1228,7 @@ private final void _parseSlowFloatValue(boolean exactNumber) _numTypesValid = NR_BIGDECIMAL; } else { // Otherwise double has to do - _numberDouble = _textBuffer.contentsAsDouble(); + _numberDouble = _textBuffer.contentsAsDouble(_owner.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER)); _numTypesValid = NR_DOUBLE; } } catch (NumberFormatException nex) { diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java index 2443d48de..c5accd5e2 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java @@ -94,8 +94,24 @@ public final static boolean inLongRange(char[] digitChars, int offset, int len, return true; } - public final static double parseDouble(String numStr) throws NumberFormatException - { - return Double.parseDouble(numStr); + /** + * @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 com.fasterxml.jackson.core.io.NumberInput.parseDouble(s, useFastParser); } } diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java index 6155ea10e..6c1099141 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java @@ -313,12 +313,24 @@ public BigDecimal contentsAsDecimal() * Convenience method for converting contents of the buffer * into a Double value. */ - public double contentsAsDouble() - throws NumberFormatException - { + public double contentsAsDouble() throws NumberFormatException { return NumberInput.parseDouble(contentsAsString()); } + /** + * 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); + } + public boolean looksLikeInt() { final char[] ch = contentsAsArray(); final int len = ch.length; diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java index 8cfea347c..1dcb87bb8 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java @@ -1,5 +1,8 @@ package com.fasterxml.jackson.dataformat.csv; +import com.fasterxml.jackson.core.StreamReadFeature; +import com.fasterxml.jackson.core.StreamWriteFeature; + import java.io.StringWriter; public class FeaturesTest extends ModuleTestBase @@ -26,4 +29,13 @@ public void testFactoryFeatures() throws Exception assertTrue(g.canUseSchema(CsvSchema.emptySchema())); g.close(); } + + public void testFactoryFastFeatures() throws Exception + { + CsvFactory f = new CsvFactory(); + f.enable(StreamReadFeature.USE_FAST_DOUBLE_PARSER.mappedFeature()); + assertTrue(f.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER.mappedFeature())); + f.enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature()); + assertTrue(f.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature())); + } } From 46eaedd04f544d8da29d7b0f3dad0cd09b762d88 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 25 Jun 2022 21:38:33 +0100 Subject: [PATCH 2/9] Update NumberOutput.java --- .../dataformat/csv/impl/NumberOutput.java | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberOutput.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberOutput.java index 9b459c72e..5d8d63a6a 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberOutput.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberOutput.java @@ -220,14 +220,40 @@ public static String toString(long value) } */ - public static String toString(double value) - { - return Double.toString(value); + /** + * @param v double + * @return double as a string + */ + public static String toString(final double v) { + return toString(v, false); } - public static String toString(float value) - { - return Float.toString(value); + /** + * @param v double + * @param useFastWriter whether to use Schubfach algorithm to write output (default false) + * @return double as a string + * @since 2.14 + */ + public static String toString(final double v, final boolean useFastWriter) { + return com.fasterxml.jackson.core.io.NumberOutput.toString(v, useFastWriter); + } + + /** + * @param v float + * @return float as a string + */ + public static String toString(final float v) { + return toString(v, false); + } + + /** + * @param v float + * @param useFastWriter whether to use Schubfach algorithm to write output (default false) + * @return float as a string + * @since 2.14 + */ + public static String toString(final float v, final boolean useFastWriter) { + return com.fasterxml.jackson.core.io.NumberOutput.toString(v, useFastWriter); } /* From 18eb088f5491f6e23b0e78050e2756be0c099da7 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 10:51:07 +0100 Subject: [PATCH 3/9] support fast double writer option --- .../jackson/dataformat/csv/CsvGenerator.java | 2 +- .../jackson/dataformat/csv/impl/CsvEncoder.java | 17 +++++++++++++++-- .../jackson/dataformat/csv/FeaturesTest.java | 10 ++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java index 853fb29b4..ecd70cef4 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java @@ -245,7 +245,7 @@ public CsvGenerator(IOContext ctxt, int jsonFeatures, int csvFeatures, _ioContext = ctxt; _formatFeatures = csvFeatures; _schema = schema; - _writer = new CsvEncoder(ctxt, csvFeatures, out, schema); + _writer = new CsvEncoder(ctxt, jsonFeatures, csvFeatures, out, schema); _writeContext = null; // just to make sure it won't be used _tokenWriteContext = SimpleTokenWriteContext.createRootContext(null); _writer.setOutputEscapes(CsvCharacterEscapes.fromCsvFeatures(csvFeatures).getEscapeCodesForAscii()); diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java index f56b6f4d0..4df1324d1 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java @@ -1,5 +1,6 @@ package com.fasterxml.jackson.dataformat.csv.impl; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.io.CharTypes; import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.dataformat.csv.CsvGenerator; @@ -116,6 +117,11 @@ public class CsvEncoder */ protected boolean _cfgEscapeControlCharWithEscapeChar; + /** + * @since 2.14 + */ + protected boolean _cfgUseFastDoubleWriter; + protected final char _cfgQuoteCharEscapeChar; /** @@ -194,9 +200,15 @@ public class CsvEncoder */ public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema) + { + this(ctxt, 0, csvFeatures, out, schema); + } + + public CsvEncoder(IOContext ctxt, int jsonFeatures, int csvFeatures, Writer out, CsvSchema schema) { _ioContext = ctxt; _csvFeatures = csvFeatures; + _cfgUseFastDoubleWriter = JsonGenerator.Feature.USE_FAST_DOUBLE_WRITER.enabledIn(jsonFeatures); _cfgOptimalQuoting = CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING.enabledIn(csvFeatures); _cfgIncludeMissingTail = !CsvGenerator.Feature.OMIT_MISSING_TAIL_COLUMNS.enabledIn(_csvFeatures); _cfgAlwaysQuoteStrings = CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS.enabledIn(csvFeatures); @@ -235,6 +247,7 @@ public CsvEncoder(CsvEncoder base, CsvSchema newSchema) { _ioContext = base._ioContext; _csvFeatures = base._csvFeatures; + _cfgUseFastDoubleWriter = base._cfgUseFastDoubleWriter; _cfgOptimalQuoting = base._cfgOptimalQuoting; _cfgIncludeMissingTail = base._cfgIncludeMissingTail; _cfgAlwaysQuoteStrings = base._cfgAlwaysQuoteStrings; @@ -586,7 +599,7 @@ protected void appendValue(long value) throws IOException protected void appendValue(float value) throws IOException { - String str = NumberOutput.toString(value); + String str = NumberOutput.toString(value, _cfgUseFastDoubleWriter); final int len = str.length(); if ((_outputTail + len) >= _outputEnd) { // >= to include possible comma too _flushBuffer(); @@ -599,7 +612,7 @@ protected void appendValue(float value) throws IOException protected void appendValue(double value) throws IOException { - String str = NumberOutput.toString(value); + String str = NumberOutput.toString(value, _cfgUseFastDoubleWriter); final int len = str.length(); if ((_outputTail + len) >= _outputEnd) { // >= to include possible comma too _flushBuffer(); diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java index 1dcb87bb8..a2c5f2a43 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java @@ -38,4 +38,14 @@ public void testFactoryFastFeatures() throws Exception f.enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature()); assertTrue(f.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature())); } + + public void testFactoryBuilderFastFeatures() throws Exception + { + CsvFactory f = CsvFactory.builder() + .enable(StreamReadFeature.USE_FAST_DOUBLE_PARSER) + .enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER) + .build(); + assertTrue(f.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER.mappedFeature())); + assertTrue(f.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature())); + } } From fa3a6d7fe8f8ae239bb356d58578c4aa1e4d7021 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 11:13:02 +0100 Subject: [PATCH 4/9] Update TestGenerator.java --- .../dataformat/csv/ser/TestGenerator.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java index 5c07ae2c1..a7eb3f365 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.StreamWriteFeature; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -119,6 +120,21 @@ public void testExplicitWithFloat() throws Exception assertEquals("abc,1.89\n", result); } + public void testExplicitWithFastFloat() throws Exception + { + CsvSchema schema = CsvSchema.builder() + .addColumn("id") + .addColumn("amount") + .build(); + + float amount = 1.89f; + //this value loses precision when converted + assertFalse(Double.toString((double)amount).equals("1.89")); + CsvMapper mapper = CsvMapper.builder().enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER).build(); + String result = mapper.writer(schema).writeValueAsString(new Entry2("abc", amount)); + assertEquals("abc,1.89\n", result); + } + public void testExplicitWithQuoted() throws Exception { CsvSchema schema = CsvSchema.builder() From 30ac1e27a26c1dfcd58514f27b1d0f3b4909d640 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 11:19:45 +0100 Subject: [PATCH 5/9] add test --- .../csv/deser/FastParserStreamingCSVReadTest.java | 15 +++++++++++++++ .../csv/deser/StreamingCSVReadTest.java | 8 ++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FastParserStreamingCSVReadTest.java diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FastParserStreamingCSVReadTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FastParserStreamingCSVReadTest.java new file mode 100644 index 000000000..73913bd9f --- /dev/null +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FastParserStreamingCSVReadTest.java @@ -0,0 +1,15 @@ +package com.fasterxml.jackson.dataformat.csv.deser; + +import com.fasterxml.jackson.core.StreamReadFeature; +import com.fasterxml.jackson.dataformat.csv.CsvFactory; + +public class FastParserStreamingCSVReadTest extends StreamingCSVReadTest { + private final CsvFactory CSV_F = CsvFactory.builder() + .enable(StreamReadFeature.USE_FAST_DOUBLE_PARSER) + .build(); + + @Override + protected CsvFactory csvFactory() { + return CSV_F; + } +} diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java index bc4d2a255..4e4df2954 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java @@ -25,6 +25,10 @@ public class StreamingCSVReadTest extends ModuleTestBase .setUseHeader(false) .build(); + protected CsvFactory csvFactory() { + return CSV_F; + } + public void testIntRead() throws Exception { _testInts(1, 59, -8); @@ -194,9 +198,9 @@ private CsvParser _parser(String csv, boolean useBytes, CsvSchema schema) { CsvParser p; if (useBytes) { - p = CSV_F.createParser(new ByteArrayInputStream(csv.getBytes("UTF-8"))); + p = csvFactory().createParser(new ByteArrayInputStream(csv.getBytes("UTF-8"))); } else { - p = CSV_F.createParser(csv); + p = csvFactory().createParser(csv); } p.setSchema(schema); return p; From baecfd379ce54d3b1e17e6ca297b632236f40276 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 13:02:02 +0100 Subject: [PATCH 6/9] Update FeaturesTest.java --- .../fasterxml/jackson/dataformat/csv/FeaturesTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java index a2c5f2a43..1a0ccbd02 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/FeaturesTest.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.StreamReadFeature; import com.fasterxml.jackson.core.StreamWriteFeature; +import java.io.StringReader; import java.io.StringWriter; public class FeaturesTest extends ModuleTestBase @@ -37,6 +38,10 @@ public void testFactoryFastFeatures() throws Exception assertTrue(f.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER.mappedFeature())); f.enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature()); assertTrue(f.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature())); + CsvParser parser = f.createParser(new StringReader("")); + assertTrue(parser.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER)); + CsvGenerator generator = f.createGenerator(new StringWriter()); + assertTrue(generator.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER)); } public void testFactoryBuilderFastFeatures() throws Exception @@ -47,5 +52,9 @@ public void testFactoryBuilderFastFeatures() throws Exception .build(); assertTrue(f.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER.mappedFeature())); assertTrue(f.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER.mappedFeature())); + CsvParser parser = f.createParser(new StringReader("")); + assertTrue(parser.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER)); + CsvGenerator generator = f.createGenerator(new StringWriter()); + assertTrue(generator.isEnabled(StreamWriteFeature.USE_FAST_DOUBLE_WRITER)); } } From 899b3483b47acf28bd4a6735c19bf6ad3ba57a75 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 20:02:41 +0100 Subject: [PATCH 7/9] some review items --- .../fasterxml/jackson/dataformat/csv/CsvGenerator.java | 3 ++- .../fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java | 8 +++++--- .../jackson/dataformat/csv/impl/NumberInput.java | 3 ++- .../fasterxml/jackson/dataformat/csv/impl/TextBuffer.java | 2 ++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java index ecd70cef4..11b25e527 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java @@ -245,7 +245,8 @@ public CsvGenerator(IOContext ctxt, int jsonFeatures, int csvFeatures, _ioContext = ctxt; _formatFeatures = csvFeatures; _schema = schema; - _writer = new CsvEncoder(ctxt, jsonFeatures, csvFeatures, out, schema); + boolean useFastDoubleWriter = StreamWriteFeature.USE_FAST_DOUBLE_WRITER.enabledIn(jsonFeatures); + _writer = new CsvEncoder(ctxt, csvFeatures, out, schema, useFastDoubleWriter); _writeContext = null; // just to make sure it won't be used _tokenWriteContext = SimpleTokenWriteContext.createRootContext(null); _writer.setOutputEscapes(CsvCharacterEscapes.fromCsvFeatures(csvFeatures).getEscapeCodesForAscii()); diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java index 4df1324d1..76840ba7c 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java @@ -199,16 +199,18 @@ public class CsvEncoder /********************************************************** */ + + @Deprecated //since 2.14 public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema) { - this(ctxt, 0, csvFeatures, out, schema); + this(ctxt, csvFeatures, out, schema, false); } - public CsvEncoder(IOContext ctxt, int jsonFeatures, int csvFeatures, Writer out, CsvSchema schema) + public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema, boolean useFastDoubleWriter) { _ioContext = ctxt; _csvFeatures = csvFeatures; - _cfgUseFastDoubleWriter = JsonGenerator.Feature.USE_FAST_DOUBLE_WRITER.enabledIn(jsonFeatures); + _cfgUseFastDoubleWriter = useFastDoubleWriter; _cfgOptimalQuoting = CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING.enabledIn(csvFeatures); _cfgIncludeMissingTail = !CsvGenerator.Feature.OMIT_MISSING_TAIL_COLUMNS.enabledIn(_csvFeatures); _cfgAlwaysQuoteStrings = CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS.enabledIn(csvFeatures); diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java index c5accd5e2..84f64807d 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/NumberInput.java @@ -98,8 +98,9 @@ public final static boolean inLongRange(char[] digitChars, int offset, int len, * @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) + * @deprecated use {@link #parseDouble(String, boolean)} */ + @Deprecated //since 2.14 public static double parseDouble(final String s) throws NumberFormatException { return parseDouble(s, false); } diff --git a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java index 6c1099141..7408dfc84 100644 --- a/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java +++ b/csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/TextBuffer.java @@ -312,7 +312,9 @@ public BigDecimal contentsAsDecimal() /** * Convenience method for converting contents of the buffer * into a Double value. + * @deprecated use {@link #contentsAsDouble(boolean)} */ + @Deprecated //since 2.14 public double contentsAsDouble() throws NumberFormatException { return NumberInput.parseDouble(contentsAsString()); } From 27feb8a9e951bbe862883738b06a38c567c454c2 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 20:08:06 +0100 Subject: [PATCH 8/9] use utf8 function where possible --- .../jackson/dataformat/csv/deser/BasicCSVParserTest.java | 6 +++--- .../jackson/dataformat/csv/deser/FormatDetectionTest.java | 4 ++-- .../jackson/dataformat/csv/deser/ParserAutoCloseTest.java | 3 ++- .../jackson/dataformat/csv/deser/StreamingCSVReadTest.java | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/BasicCSVParserTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/BasicCSVParserTest.java index 1b2d36f8c..7e4e428dd 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/BasicCSVParserTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/BasicCSVParserTest.java @@ -54,7 +54,7 @@ private void _testSimpleExplicit(ObjectReader r, boolean useBytes) throws Except if (useBytes) { user = r.readValue(INPUT); } else { - user = r.readValue(INPUT.getBytes("UTF-8")); + user = r.readValue(utf8(INPUT)); } assertEquals("Bob", user.firstName); assertEquals("Robertson", user.lastName); @@ -72,7 +72,7 @@ public void testSimpleExplicitWithBOM() throws Exception { // first, UTF-8 BOM: b.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}); - b.write("Bob,Robertson,MALE,AQIDBAU=,false\n".getBytes("UTF-8")); + b.write(utf8("Bob,Robertson,MALE,AQIDBAU=,false\n")); b.close(); user = r.readValue(b.toByteArray()); @@ -139,7 +139,7 @@ private void _testMapsWithLinefeeds(boolean useBytes) throws Exception { MappingIterator> mi; if (useBytes) { - mi = or.readValues(CSV.getBytes("UTF-8")); + mi = or.readValues(utf8(CSV)); } else { mi = or.readValues(CSV); } diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FormatDetectionTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FormatDetectionTest.java index ef6cab631..caa03ed40 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FormatDetectionTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/FormatDetectionTest.java @@ -14,7 +14,7 @@ public void testSimpleObjectWithHeader() throws IOException { CsvFactory f = new CsvFactory(); DataFormatDetector detector = new DataFormatDetector(f); - byte[] doc = "name,place,town\nBob,home,Denver\n".getBytes("UTF-8"); + byte[] doc = utf8("name,place,town\nBob,home,Denver\n"); DataFormatMatcher matcher = detector.findFormat(doc); // should have match assertTrue(matcher.hasMatch()); @@ -23,7 +23,7 @@ public void testSimpleObjectWithHeader() throws IOException assertSame(f, matcher.getMatch()); // and also something that does NOT look like CSV - doc = "{\"a\":3}".getBytes("UTF-8"); + doc = utf8("{\"a\":3}"); matcher = detector.findFormat(doc); assertFalse(matcher.hasMatch()); } diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/ParserAutoCloseTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/ParserAutoCloseTest.java index e6b643297..6913266a1 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/ParserAutoCloseTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/ParserAutoCloseTest.java @@ -3,6 +3,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; +import java.nio.charset.StandardCharsets; import org.junit.Assert; @@ -80,7 +81,7 @@ public static class CloseTrackerOutputStream extends ByteArrayInputStream { private boolean closed; public CloseTrackerOutputStream(String s) { - super(s.getBytes()); + super(s.getBytes(StandardCharsets.UTF_8)); } @Override diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java index 4e4df2954..f5ea95eb2 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/StreamingCSVReadTest.java @@ -198,7 +198,7 @@ private CsvParser _parser(String csv, boolean useBytes, CsvSchema schema) { CsvParser p; if (useBytes) { - p = csvFactory().createParser(new ByteArrayInputStream(csv.getBytes("UTF-8"))); + p = csvFactory().createParser(new ByteArrayInputStream(utf8(csv))); } else { p = csvFactory().createParser(csv); } From 0a52a8c1bf38b4305e9f07ba65e514e4152ad87c Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sun, 26 Jun 2022 20:11:14 +0100 Subject: [PATCH 9/9] Update TestGenerator.java --- .../fasterxml/jackson/dataformat/csv/ser/TestGenerator.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java index a7eb3f365..c7bce7653 100644 --- a/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java +++ b/csv/src/test/java/com/fasterxml/jackson/dataformat/csv/ser/TestGenerator.java @@ -114,8 +114,7 @@ public void testExplicitWithFloat() throws Exception .build(); float amount = 1.89f; - //this value loses precision when converted - assertFalse(Double.toString((double)amount).equals("1.89")); + assertFalse(Double.toString(amount).equals("1.89")); String result = MAPPER.writer(schema).writeValueAsString(new Entry2("abc", amount)); assertEquals("abc,1.89\n", result); } @@ -128,8 +127,7 @@ public void testExplicitWithFastFloat() throws Exception .build(); float amount = 1.89f; - //this value loses precision when converted - assertFalse(Double.toString((double)amount).equals("1.89")); + assertFalse(Double.toString(amount).equals("1.89")); CsvMapper mapper = CsvMapper.builder().enable(StreamWriteFeature.USE_FAST_DOUBLE_WRITER).build(); String result = mapper.writer(schema).writeValueAsString(new Entry2("abc", amount)); assertEquals("abc,1.89\n", result);