@@ -113,6 +113,9 @@ public class CsvEncoder
113
113
114
114
protected boolean _cfgAlwaysQuoteEmptyStrings ;
115
115
116
+ // @since 2.16
117
+ protected boolean _cfgAlwaysQuoteNumbers ;
118
+
116
119
protected boolean _cfgEscapeQuoteCharWithEscapeChar ;
117
120
118
121
/**
@@ -218,6 +221,7 @@ public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema,
218
221
_cfgIncludeMissingTail = !CsvGenerator .Feature .OMIT_MISSING_TAIL_COLUMNS .enabledIn (_csvFeatures );
219
222
_cfgAlwaysQuoteStrings = CsvGenerator .Feature .ALWAYS_QUOTE_STRINGS .enabledIn (csvFeatures );
220
223
_cfgAlwaysQuoteEmptyStrings = CsvGenerator .Feature .ALWAYS_QUOTE_EMPTY_STRINGS .enabledIn (csvFeatures );
224
+ _cfgAlwaysQuoteNumbers = CsvGenerator .Feature .ALWAYS_QUOTE_NUMBERS .enabledIn (csvFeatures );
221
225
_cfgEscapeQuoteCharWithEscapeChar = CsvGenerator .Feature .ESCAPE_QUOTE_CHAR_WITH_ESCAPE_CHAR .enabledIn (csvFeatures );
222
226
_cfgEscapeControlCharWithEscapeChar = Feature .ESCAPE_CONTROL_CHARS_WITH_ESCAPE_CHAR .enabledIn (csvFeatures );
223
227
@@ -257,6 +261,8 @@ public CsvEncoder(CsvEncoder base, CsvSchema newSchema)
257
261
_cfgIncludeMissingTail = base ._cfgIncludeMissingTail ;
258
262
_cfgAlwaysQuoteStrings = base ._cfgAlwaysQuoteStrings ;
259
263
_cfgAlwaysQuoteEmptyStrings = base ._cfgAlwaysQuoteEmptyStrings ;
264
+ _cfgAlwaysQuoteNumbers = base ._cfgAlwaysQuoteNumbers ;
265
+
260
266
_cfgEscapeQuoteCharWithEscapeChar = base ._cfgEscapeQuoteCharWithEscapeChar ;
261
267
_cfgEscapeControlCharWithEscapeChar = base ._cfgEscapeControlCharWithEscapeChar ;
262
268
@@ -329,6 +335,7 @@ public CsvEncoder overrideFormatFeatures(int feat) {
329
335
_cfgIncludeMissingTail = !CsvGenerator .Feature .OMIT_MISSING_TAIL_COLUMNS .enabledIn (feat );
330
336
_cfgAlwaysQuoteStrings = CsvGenerator .Feature .ALWAYS_QUOTE_STRINGS .enabledIn (feat );
331
337
_cfgAlwaysQuoteEmptyStrings = CsvGenerator .Feature .ALWAYS_QUOTE_EMPTY_STRINGS .enabledIn (feat );
338
+ _cfgAlwaysQuoteNumbers = CsvGenerator .Feature .ALWAYS_QUOTE_NUMBERS .enabledIn (feat );
332
339
_cfgEscapeQuoteCharWithEscapeChar = CsvGenerator .Feature .ESCAPE_QUOTE_CHAR_WITH_ESCAPE_CHAR .enabledIn (feat );
333
340
_cfgEscapeControlCharWithEscapeChar = Feature .ESCAPE_CONTROL_CHARS_WITH_ESCAPE_CHAR .enabledIn (feat );
334
341
}
@@ -407,14 +414,20 @@ public final void write(int columnIndex, int value) throws IOException
407
414
// easy case: all in order
408
415
if (columnIndex == _nextColumnToWrite ) {
409
416
// inlined 'appendValue(int)'
410
- // up to 10 digits and possible minus sign, leading comma
411
- if ((_outputTail + 12 ) > _outputEnd ) {
417
+ // up to 10 digits and possible minus sign, leading comma, possible quotes
418
+ if ((_outputTail + 14 ) > _outputEnd ) {
412
419
_flushBuffer ();
413
420
}
414
421
if (_nextColumnToWrite > 0 ) {
415
422
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
416
423
}
424
+ if (_cfgAlwaysQuoteNumbers ) {
425
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
426
+ }
417
427
_outputTail = NumberOutput .outputInt (value , _outputBuffer , _outputTail );
428
+ if (_cfgAlwaysQuoteNumbers ) {
429
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
430
+ }
418
431
++_nextColumnToWrite ;
419
432
return ;
420
433
}
@@ -426,14 +439,20 @@ public final void write(int columnIndex, long value) throws IOException
426
439
// easy case: all in order
427
440
if (columnIndex == _nextColumnToWrite ) {
428
441
// inlined 'appendValue(int)'
429
- // up to 20 digits, minus sign, leading comma
430
- if ((_outputTail + 22 ) > _outputEnd ) {
442
+ // up to 20 digits, minus sign, leading comma, possible quotes
443
+ if ((_outputTail + 24 ) > _outputEnd ) {
431
444
_flushBuffer ();
432
445
}
433
446
if (_nextColumnToWrite > 0 ) {
434
447
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
435
448
}
449
+ if (_cfgAlwaysQuoteNumbers ) {
450
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
451
+ }
436
452
_outputTail = NumberOutput .outputLong (value , _outputBuffer , _outputTail );
453
+ if (_cfgAlwaysQuoteNumbers ) {
454
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
455
+ }
437
456
++_nextColumnToWrite ;
438
457
return ;
439
458
}
@@ -607,28 +626,40 @@ protected void appendRawValue(String value) throws IOException
607
626
608
627
protected void appendValue (int value ) throws IOException
609
628
{
610
- // up to 10 digits and possible minus sign, leading comma
611
- if ((_outputTail + 12 ) > _outputEnd ) {
629
+ // up to 10 digits and possible minus sign, leading comma, possible quotes
630
+ if ((_outputTail + 14 ) > _outputEnd ) {
612
631
_flushBuffer ();
613
632
}
614
633
if (_nextColumnToWrite > 0 ) {
615
634
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
616
635
}
636
+ if (_cfgAlwaysQuoteNumbers ) {
637
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
638
+ }
617
639
_outputTail = NumberOutput .outputInt (value , _outputBuffer , _outputTail );
640
+ if (_cfgAlwaysQuoteNumbers ) {
641
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
642
+ }
618
643
}
619
644
620
645
protected void appendValue (long value ) throws IOException
621
646
{
622
- // up to 20 digits, minus sign, leading comma
623
- if ((_outputTail + 22 ) > _outputEnd ) {
647
+ // up to 20 digits, minus sign, leading comma, possible quotes
648
+ if ((_outputTail + 24 ) > _outputEnd ) {
624
649
_flushBuffer ();
625
650
}
626
651
if (_nextColumnToWrite > 0 ) {
627
652
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
628
653
}
654
+ if (_cfgAlwaysQuoteNumbers ) {
655
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
656
+ }
629
657
_outputTail = NumberOutput .outputLong (value , _outputBuffer , _outputTail );
658
+ if (_cfgAlwaysQuoteNumbers ) {
659
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
660
+ }
630
661
}
631
-
662
+
632
663
protected void appendValue (float value ) throws IOException
633
664
{
634
665
String str = NumberOutput .toString (value , _cfgUseFastDoubleWriter );
@@ -639,7 +670,7 @@ protected void appendValue(float value) throws IOException
639
670
if (_nextColumnToWrite > 0 ) {
640
671
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
641
672
}
642
- writeRaw (str );
673
+ writeNumber (str );
643
674
}
644
675
645
676
protected void appendValue (double value ) throws IOException
@@ -652,11 +683,11 @@ protected void appendValue(double value) throws IOException
652
683
if (_nextColumnToWrite > 0 ) {
653
684
_outputBuffer [_outputTail ++] = _cfgColumnSeparator ;
654
685
}
655
- writeRaw (str );
686
+ writeNumber (str );
656
687
}
657
688
658
689
// @since 2.16: pre-encoded BigInteger/BigDecimal value
659
- protected void appendNumberValue (String numValue ) throws IOException
690
+ protected void appendNumberValue (String numStr ) throws IOException
660
691
{
661
692
// Same as "appendRawValue()", except may want quoting
662
693
if (_outputTail >= _outputEnd ) {
@@ -665,7 +696,7 @@ protected void appendNumberValue(String numValue) throws IOException
665
696
if (_nextColumnToWrite > 0 ) {
666
697
appendColumnSeparator ();
667
698
}
668
- writeRaw ( numValue );
699
+ writeNumber ( numStr );
669
700
}
670
701
671
702
protected void appendValue (boolean value ) throws IOException {
@@ -702,7 +733,7 @@ protected void appendColumnSeparator() throws IOException {
702
733
/* Output methods, unprocessed ("raw")
703
734
/**********************************************************
704
735
*/
705
-
736
+
706
737
public void writeRaw (String text ) throws IOException
707
738
{
708
739
// Nothing to check, can just output as is
@@ -788,6 +819,25 @@ private void writeRawLong(String text) throws IOException
788
819
_outputTail = len ;
789
820
}
790
821
822
+ // @since 2.16
823
+ private void writeNumber (String text ) throws IOException
824
+ {
825
+ final int len = text .length ();
826
+ if ((_outputTail + len + 2 ) > _outputEnd ) {
827
+ _flushBuffer ();
828
+ }
829
+
830
+ if (_cfgAlwaysQuoteNumbers ) {
831
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
832
+ text .getChars (0 , len , _outputBuffer , _outputTail );
833
+ _outputTail += len ;
834
+ _outputBuffer [_outputTail ++] = (char ) _cfgQuoteCharacter ;
835
+ } else {
836
+ text .getChars (0 , len , _outputBuffer , _outputTail );
837
+ _outputTail += len ;
838
+ }
839
+ }
840
+
791
841
/*
792
842
/**********************************************************
793
843
/* Output methods, with quoting and escaping
0 commit comments