From ed491993e0af0fcce1cc94fd378ca2242e6fd1de Mon Sep 17 00:00:00 2001 From: Stephen Olander-Waters Date: Mon, 18 Feb 2019 21:41:47 -0600 Subject: [PATCH] [CSV-234] Enable escaping of quotes in Clobs --- .../org/apache/commons/csv/CSVFormat.java | 40 +++++++++++++++---- .../apache/commons/csv/CSVPrinterTest.java | 5 ++- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/apache/commons/csv/CSVFormat.java b/src/main/java/org/apache/commons/csv/CSVFormat.java index 7fcf830486..6f77bef535 100644 --- a/src/main/java/org/apache/commons/csv/CSVFormat.java +++ b/src/main/java/org/apache/commons/csv/CSVFormat.java @@ -1240,8 +1240,7 @@ private void print(final Reader reader, final Appendable out, final boolean newR out.append(getDelimiter()); } if (isQuoteCharacterSet()) { - // the original object is needed so can check for Number - printWithQuotes(reader, out, newRecord); + printWithQuotes(reader, out); } else if (isEscapeCharacterSet()) { printWithEscapes(reader, out); } else if (out instanceof Writer) { @@ -1501,18 +1500,43 @@ private void printWithQuotes(final Object object, final CharSequence value, fina * * @throws IOException */ - private void printWithQuotes(final Reader reader, final Appendable out, final boolean newRecord) - throws IOException { - final char quoteChar = getQuoteCharacter().charValue(); + private void printWithQuotes(final Reader reader, final Appendable out) throws IOException { if (getQuoteMode() == QuoteMode.NONE) { printWithEscapes(reader, out); return; } - out.append(quoteChar); - IOUtils.copy(reader, out); - out.append(quoteChar); + int pos = 0; + + final char quote = getQuoteCharacter().charValue(); + final StringBuilder builder = new StringBuilder(IOUtils.DEFAULT_BUFFER_SIZE); + + out.append(quote); + + int c; + while (-1 != (c = reader.read())) { + builder.append((char) c); + if (c == quote) { + // write out segment up until this char + if (pos > 0) { + out.append(builder.substring(0, pos)); + builder.setLength(0); + pos = -1; + } + + out.append(quote); + out.append((char) c); + } + pos++; + } + + // write last segment + if (pos > 0) { + out.append(builder.substring(0, pos)); + } + + out.append(quote); } @Override diff --git a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java index 18856cf16e..6a0e3afc71 100644 --- a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java +++ b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java @@ -219,8 +219,11 @@ private void setUpTable(final Connection connection) throws SQLException { try (final Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), TEXT CLOB)"); statement.execute("insert into TEST values(1, 'r1', 'long text 1')"); - longText2 = StringUtils.repeat('a', (IOUtils.DEFAULT_BUFFER_SIZE * 2) + 1); + longText2 = StringUtils.repeat('a', IOUtils.DEFAULT_BUFFER_SIZE - 4); + longText2 += "\"\r\n\"a\""; + longText2 += StringUtils.repeat('a', IOUtils.DEFAULT_BUFFER_SIZE - 1); statement.execute("insert into TEST values(2, 'r2', '" + longText2 + "')"); + longText2 = longText2.replace("\"","\"\""); } }