fix for forced unquoted tabulator-separated csv writing

This commit is contained in:
Jörg Prante 2022-06-24 17:20:05 +02:00
parent e1e9a35cd7
commit fdd791dcd5

View file

@ -9,7 +9,7 @@ import java.util.List;
public class Generator implements Constants, Closeable, Flushable { public class Generator implements Constants, Closeable, Flushable {
private static final String LF = System.getProperty("line.separator"); private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private final Writer writer; private final Writer writer;
@ -25,6 +25,8 @@ public class Generator implements Constants, Closeable, Flushable {
private boolean alwaysQuote; private boolean alwaysQuote;
private boolean neverQuote;
public Generator(Writer writer) { public Generator(Writer writer) {
this.writer = writer; this.writer = writer;
this.col = 0; this.col = 0;
@ -41,6 +43,11 @@ public class Generator implements Constants, Closeable, Flushable {
return this; return this;
} }
public Generator setNeverQuote(boolean neverQuote) {
this.neverQuote = neverQuote;
return this;
}
public Generator setQuote(char quote) { public Generator setQuote(char quote) {
this.quote = quote; this.quote = quote;
return this; return this;
@ -59,15 +66,16 @@ public class Generator implements Constants, Closeable, Flushable {
} }
public synchronized void write(String value) throws IOException { public synchronized void write(String value) throws IOException {
if (value == null) {
throw new IllegalArgumentException("null value not allowed");
}
if (col > 0) { if (col > 0) {
writer.write(separator); writer.write(separator);
} }
if (value != null) { writer.write(maybeEscape(value));
writer.write(escape(value));
}
col++; col++;
if (col >= keys.size()) { if (col >= keys.size()) {
writer.write(LF); writer.write(LINE_SEPARATOR);
row++; row++;
col = 0; col = 0;
} }
@ -91,13 +99,29 @@ public class Generator implements Constants, Closeable, Flushable {
writer.flush(); writer.flush();
} }
private String escape(String value) { private String maybeEscape(String value) {
if (!alwaysQuote && value.indexOf(quote) < 0 if (alwaysQuote) {
&& value.indexOf(COMMA) < 0 return escape(value);
&& value.indexOf(TAB) < 0 }
&& !value.contains(LF)) { if (neverQuote) {
return value; return value;
} }
if (value.indexOf(quote) < 0
&& value.indexOf(separator) < 0
&& value.indexOf(TAB) < 0
&& value.indexOf(FF) < 0
&& value.indexOf(CR) < 0
&& value.indexOf(LF) < 0
&& value.indexOf(BACKSPACE) < 0
&& !value.contains(LINE_SEPARATOR)) {
return value;
} else {
return escape(value);
}
}
private String escape(String value) {
// escape means, surround the value by the quote character and emit quote character with the value twice
int length = value.length(); int length = value.length();
StringBuilder sb = new StringBuilder(length + 2); StringBuilder sb = new StringBuilder(length + 2);
sb.append(quote); sb.append(quote);
@ -111,5 +135,4 @@ public class Generator implements Constants, Closeable, Flushable {
sb.append(quote); sb.append(quote);
return sb.toString(); return sb.toString();
} }
} }