Skip to content

Commit 660be95

Browse files
authored
Merge pull request #609 from rootvector2/none-quote-escape
Escape quote char in printWithEscapes when QuoteMode is NONE
2 parents 19b2913 + 27a439a commit 660be95

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,12 +2324,14 @@ private void printWithEscapes(final CharSequence charSeq, final Appendable appen
23242324
final char[] delimArray = getDelimiterCharArray();
23252325
final int delimLength = delimArray.length;
23262326
final char escape = getEscapeChar();
2327+
final boolean quoteSet = isQuoteCharacterSet();
2328+
final char quote = quoteSet ? getQuoteCharacter().charValue() : 0;
23272329
while (pos < end) {
23282330
char c = charSeq.charAt(pos);
23292331
final boolean isDelimiterStart = isDelimiter(c, charSeq, pos, delimArray, delimLength);
23302332
final boolean isCr = c == Constants.CR;
23312333
final boolean isLf = c == Constants.LF;
2332-
if (isCr || isLf || c == escape || isDelimiterStart) {
2334+
if (isCr || isLf || c == escape || quoteSet && c == quote || isDelimiterStart) {
23332335
// write out segment up until this char
23342336
if (pos > start) {
23352337
appendable.append(charSeq, start, pos);
@@ -2368,6 +2370,8 @@ private void printWithEscapes(final Reader reader, final Appendable appendable)
23682370
final char[] delimArray = getDelimiterCharArray();
23692371
final int delimLength = delimArray.length;
23702372
final char escape = getEscapeChar();
2373+
final boolean quoteSet = isQuoteCharacterSet();
2374+
final char quote = quoteSet ? getQuoteCharacter().charValue() : 0;
23712375
final StringBuilder builder = new StringBuilder(IOUtils.DEFAULT_BUFFER_SIZE);
23722376
int c;
23732377
final char[] lookAheadBuffer = new char[delimLength - 1];
@@ -2379,7 +2383,7 @@ private void printWithEscapes(final Reader reader, final Appendable appendable)
23792383
final boolean isDelimiterStart = isDelimiter((char) c, test, pos, delimArray, delimLength);
23802384
final boolean isCr = c == Constants.CR;
23812385
final boolean isLf = c == Constants.LF;
2382-
if (isCr || isLf || c == escape || isDelimiterStart) {
2386+
if (isCr || isLf || c == escape || quoteSet && c == quote || isDelimiterStart) {
23832387
// write out segment up until this char
23842388
if (pos > start) {
23852389
append(builder.substring(start, pos), appendable);

src/test/java/org/apache/commons/csv/CSVPrinterTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,26 @@ void testDelimeterStringQuoteNone() throws IOException {
423423
}
424424
}
425425

426+
@Test
427+
void testQuoteCharEscapedWithQuoteModeNone() throws IOException {
428+
final CSVFormat format = CSVFormat.DEFAULT.builder().setQuote('"').setEscape('?').setQuoteMode(QuoteMode.NONE).get();
429+
final StringWriter sw = new StringWriter();
430+
try (CSVPrinter printer = new CSVPrinter(sw, format)) {
431+
printer.printRecord("\"abc", "x\"y");
432+
printer.printRecord(new StringReader("\"abc"), new StringReader("x\"y"));
433+
}
434+
assertEquals("?\"abc,x?\"y" + RECORD_SEPARATOR + "?\"abc,x?\"y" + RECORD_SEPARATOR, sw.toString());
435+
// The emitted records must read back as the original values.
436+
try (CSVParser parser = CSVParser.parse(sw.toString(), format)) {
437+
final List<CSVRecord> records = parser.getRecords();
438+
assertEquals(2, records.size());
439+
for (final CSVRecord record : records) {
440+
assertEquals("\"abc", record.get(0));
441+
assertEquals("x\"y", record.get(1));
442+
}
443+
}
444+
}
445+
426446
@Test
427447
void testDelimiterEscaped() throws IOException {
428448
final StringWriter sw = new StringWriter();

0 commit comments

Comments
 (0)