@@ -177,13 +177,23 @@ private Feature(boolean defaultState) {
177
177
*/
178
178
// 02-Apr-2019, tatu: Some names will look funny if escaped: let's leave out
179
179
// single letter case (esp so 'y' won't get escaped)
180
- private final static Set <String > RESERVED_NAMES = new HashSet <>(Arrays .asList (
180
+ private final static Set <String > MUST_QUOTE_NAMES = new HashSet <>(Arrays .asList (
181
181
// "y", "Y", "n", "N",
182
182
"yes" , "Yes" , "YES" , "no" , "No" , "NO" ,
183
183
"true" , "True" , "TRUE" , "false" , "False" , "FALSE" ,
184
184
"on" , "On" , "ON" , "off" , "Off" , "OFF"
185
185
));
186
186
187
+ /**
188
+ * As per YAML <a href="https://yaml.org/type/null.html">null</a>
189
+ * and <a href="https://yaml.org/type/bool.html">boolean</a> type specs,
190
+ * better retain quoting for some values
191
+ */
192
+ private final static Set <String > MUST_QUOTE_VALUES = new HashSet <>(Arrays .asList (
193
+ "true" , "True" , "TRUE" , "false" , "False" , "FALSE" ,
194
+ "null" , "Null" , "NULL"
195
+ ));
196
+
187
197
/*
188
198
/**********************************************************
189
199
/* Configuration
@@ -444,35 +454,9 @@ public final void writeStringField(String fieldName, String value)
444
454
private final void _writeFieldName (String name ) throws IOException
445
455
{
446
456
_writeScalar (name , "string" ,
447
- _needQuoting (name ) ? STYLE_QUOTED : STYLE_UNQUOTED_NAME );
457
+ _nameNeedsQuoting (name ) ? STYLE_QUOTED : STYLE_UNQUOTED_NAME );
448
458
}
449
459
450
- private boolean _needQuoting (String name ) {
451
- if (name .length () == 0 ) {
452
- return false ;
453
- }
454
- switch (name .charAt (0 )) {
455
- // First, reserved name starting chars:
456
- case 'f' : // false
457
- case 'o' : // on/off
458
- case 'n' : // no
459
- case 't' : // true
460
- case 'y' : // yes
461
- case 'F' : // False
462
- case 'O' : // On/Off
463
- case 'N' : // No
464
- case 'T' : // True
465
- case 'Y' : // Yes
466
- return RESERVED_NAMES .contains (name );
467
-
468
- // And then numbers
469
- case '0' : case '1' : case '2' : case '3' : case '4' :
470
- case '5' : case '6' : case '7' : case '8' : case '9' :
471
- case '-' : case '+' : case '.' :
472
- return true ;
473
- }
474
- return false ;
475
- }
476
460
/*
477
461
/**********************************************************
478
462
/* Public API: low-level I/O
@@ -588,25 +572,25 @@ public void writeString(String text) throws IOException,JsonGenerationException
588
572
return ;
589
573
}
590
574
_verifyValueWrite ("write String value" );
591
- DumperOptions .ScalarStyle style ;
592
575
593
576
// [dataformats-text#50]: Empty String always quoted
594
577
if (text .isEmpty ()) {
595
- style = STYLE_QUOTED ;
596
- } else if (Feature .MINIMIZE_QUOTES .enabledIn (_formatFeatures )) {
597
- if (isBooleanContent (text )) {
598
- style = STYLE_QUOTED ;
599
- // If this string could be interpreted as a number, it must be quoted.
600
- } else if (Feature .ALWAYS_QUOTE_NUMBERS_AS_STRINGS .enabledIn (_formatFeatures )
601
- && PLAIN_NUMBER_P .matcher (text ).matches ()) {
578
+ _writeScalar (text , "string" , STYLE_QUOTED );
579
+ return ;
580
+ }
581
+ DumperOptions .ScalarStyle style ;
582
+ if (Feature .MINIMIZE_QUOTES .enabledIn (_formatFeatures )) {
583
+ // If one of reserved values ("true", "null"), or, number, preserve quoting:
584
+ if (_valueNeedsQuoting (text )
585
+ || (Feature .ALWAYS_QUOTE_NUMBERS_AS_STRINGS .enabledIn (_formatFeatures )
586
+ && PLAIN_NUMBER_P .matcher (text ).matches ())
587
+ ) {
602
588
style = STYLE_QUOTED ;
603
589
} else if (text .indexOf ('\n' ) >= 0 ) {
604
590
style = STYLE_LITERAL ;
605
591
} else {
606
592
style = STYLE_PLAIN ;
607
593
}
608
- _writeScalar (text , "string" , style );
609
- return ;
610
594
} else {
611
595
if (Feature .LITERAL_BLOCK_STYLE .enabledIn (_formatFeatures ) && text .indexOf ('\n' ) >= 0 ) {
612
596
style = STYLE_LITERAL ;
@@ -617,10 +601,6 @@ public void writeString(String text) throws IOException,JsonGenerationException
617
601
_writeScalar (text , "string" , style );
618
602
}
619
603
620
- private boolean isBooleanContent (String text ) {
621
- return "true" .equals (text ) || "false" .equals (text );
622
- }
623
-
624
604
@ Override
625
605
public void writeString (char [] text , int offset , int len ) throws IOException
626
606
{
@@ -944,6 +924,47 @@ private String _base64encode(final Base64Variant b64v, final byte[] input, final
944
924
return sb .toString ();
945
925
}
946
926
927
+ private boolean _nameNeedsQuoting (String name ) {
928
+ if (name .length () == 0 ) { // empty String does indeed require quoting
929
+ return true ;
930
+ }
931
+ switch (name .charAt (0 )) {
932
+ // First, reserved name starting chars:
933
+ case 'f' : // false
934
+ case 'o' : // on/off
935
+ case 'n' : // no
936
+ case 't' : // true
937
+ case 'y' : // yes
938
+ case 'F' : // False
939
+ case 'O' : // On/Off
940
+ case 'N' : // No
941
+ case 'T' : // True
942
+ case 'Y' : // Yes
943
+ return MUST_QUOTE_NAMES .contains (name );
944
+
945
+ // And then numbers
946
+ case '0' : case '1' : case '2' : case '3' : case '4' :
947
+ case '5' : case '6' : case '7' : case '8' : case '9' :
948
+ case '-' : case '+' : case '.' :
949
+ return true ;
950
+ }
951
+ return false ;
952
+ }
953
+
954
+ private boolean _valueNeedsQuoting (String name ) {
955
+ switch (name .charAt (0 )) { // caller ensures no empty String
956
+ // First, reserved name starting chars:
957
+ case 'f' : // false
958
+ case 'n' : // null
959
+ case 't' : // true
960
+ case 'F' : // False/FALSE
961
+ case 'N' : // Null/NULL
962
+ case 'T' : // True/TRUE
963
+ return MUST_QUOTE_VALUES .contains (name );
964
+ }
965
+ return false ;
966
+ }
967
+
947
968
protected String _lf () {
948
969
return _outputOptions .getLineBreak ().getString ();
949
970
}
0 commit comments