@@ -39,8 +39,10 @@ public final class CSVPrinter implements Flushable, Closeable {
3939 private final Appendable out ;
4040 private final CSVFormat format ;
4141
42- /** True if we just began a new record. */
43- private boolean newRecord = true ;
42+ /** 0 if we just began a new record. */
43+ private int newRecord = 0 ;
44+ /** true if first value is empty */
45+ private boolean firstEmpty ;
4446
4547 /**
4648 * Creates a printer that will print values to the given stream following the CSVFormat.
@@ -133,7 +135,7 @@ public void print(final Object value) throws IOException {
133135
134136 private void print (final Object object , final CharSequence value , final int offset , final int len )
135137 throws IOException {
136- if (! newRecord ) {
138+ if (newRecord > 0 ) {
137139 out .append (format .getDelimiter ());
138140 }
139141 if (object == null ) {
@@ -146,7 +148,7 @@ private void print(final Object object, final CharSequence value, final int offs
146148 } else {
147149 out .append (value , offset , offset + len );
148150 }
149- newRecord = false ;
151+ newRecord ++ ;
150152 }
151153
152154 /*
@@ -219,18 +221,16 @@ private void printAndQuote(final Object object, final CharSequence value, final
219221 return ;
220222 case MINIMAL :
221223 if (len <= 0 ) {
222- // always quote an empty token that is the first
223- // on the line, as it may be the only thing on the
224- // line. If it were not quoted in that case,
225- // an empty line has no tokens.
226- if (newRecord ) {
227- quote = true ;
224+ // mark quotes may be required for first empty value
225+ if (newRecord == 0 ) {
226+ firstEmpty = true ;
227+ return ;
228228 }
229229 } else {
230230 char c = value .charAt (pos );
231231
232232 // TODO where did this rule come from?
233- if (newRecord && (c < '0' || (c > '9' && c < 'A' ) || (c > 'Z' && c < 'a' ) || (c > 'z' ))) {
233+ if (newRecord == 0 && (c < '0' || (c > '9' && c < 'A' ) || (c > 'Z' && c < 'a' ) || (c > 'z' ))) {
234234 quote = true ;
235235 } else if (c <= COMMENT ) {
236236 // Some other chars at the start of a value caused the parser to fail, so for now
@@ -318,7 +318,7 @@ public void printComment(final String comment) throws IOException {
318318 if (!format .isCommentMarkerSet ()) {
319319 return ;
320320 }
321- if (! newRecord ) {
321+ if (newRecord > 0 ) {
322322 println ();
323323 }
324324 out .append (format .getCommentMarker ().charValue ());
@@ -351,11 +351,20 @@ public void printComment(final String comment) throws IOException {
351351 * If an I/O error occurs
352352 */
353353 public void println () throws IOException {
354+ // if the line only contains an empty value
355+ if (newRecord == 1 && firstEmpty
356+ && (format .getQuoteMode () == null || format .getQuoteMode () == QuoteMode .MINIMAL )) {
357+ final char quoteChar = format .getQuoteCharacter ().charValue ();
358+ out .append (quoteChar );
359+ out .append (quoteChar );
360+ }
361+
354362 final String recordSeparator = format .getRecordSeparator ();
355363 if (recordSeparator != null ) {
356364 out .append (recordSeparator );
357365 }
358- newRecord = true ;
366+ newRecord = 0 ;
367+ firstEmpty = false ;
359368 }
360369
361370 /**
0 commit comments