@@ -159,6 +159,14 @@ public int getFirstTag() {
159
159
*/
160
160
protected TagList _tagValues = new TagList ();
161
161
162
+ /**
163
+ * When major type 7 value is encountered and exposed as {@link JsonToken#VALUE_EMBEDDED_OBJECT},
164
+ * the value will be stored here.
165
+ *
166
+ * @since 2.20
167
+ */
168
+ protected CBORSimpleValue _simpleValue ;
169
+
162
170
/**
163
171
* Flag that indicates that the current token has not yet
164
172
* been fully processed, and needs to be finished for
@@ -506,9 +514,9 @@ public JsonToken nextToken() throws JacksonException
506
514
_skipIncomplete ();
507
515
}
508
516
_tokenInputTotal = _currInputProcessed + _inputPtr ;
509
- // also: clear any data retained so far
510
- _numTypesValid = NR_UNKNOWN ;
511
- _binaryValue = null ;
517
+
518
+ // also: clear any data retained for previous token
519
+ clearRetainedValues () ;
512
520
513
521
// First: need to keep track of lengths of defined-length Arrays and
514
522
// Objects (to materialize END_ARRAY/END_OBJECT as necessary);
@@ -1135,12 +1143,12 @@ public boolean nextName(SerializableString str) throws JacksonException
1135
1143
{
1136
1144
// Two parsing modes; can only succeed if expecting field name, so handle that first:
1137
1145
if (_streamReadContext .inObject () && _currToken != JsonToken .PROPERTY_NAME ) {
1138
- _numTypesValid = NR_UNKNOWN ;
1139
1146
if (_tokenIncomplete ) {
1140
1147
_skipIncomplete ();
1141
1148
}
1142
1149
_tokenInputTotal = _currInputProcessed + _inputPtr ;
1143
- _binaryValue = null ;
1150
+ // need to clear retained values for previous token
1151
+ clearRetainedValues ();
1144
1152
_tagValues .clear ();
1145
1153
// completed the whole Object?
1146
1154
if (!_streamReadContext .expectMoreValues ()) {
@@ -1195,12 +1203,12 @@ public boolean nextName(SerializableString str) throws JacksonException
1195
1203
public String nextName () throws JacksonException
1196
1204
{
1197
1205
if (_streamReadContext .inObject () && _currToken != JsonToken .PROPERTY_NAME ) {
1198
- _numTypesValid = NR_UNKNOWN ;
1199
1206
if (_tokenIncomplete ) {
1200
1207
_skipIncomplete ();
1201
1208
}
1202
1209
_tokenInputTotal = _currInputProcessed + _inputPtr ;
1203
- _binaryValue = null ;
1210
+ // need to clear retained values for previous token
1211
+ clearRetainedValues ();
1204
1212
_tagValues .clear ();
1205
1213
// completed the whole Object?
1206
1214
if (!_streamReadContext .expectMoreValues ()) {
@@ -1362,9 +1370,8 @@ public int nextNameMatch(PropertyNameMatcher matcher) throws JacksonException
1362
1370
if (_tokenIncomplete ) {
1363
1371
_skipIncomplete ();
1364
1372
}
1365
- _numTypesValid = NR_UNKNOWN ;
1366
1373
_tokenInputTotal = _currInputProcessed + _inputPtr ;
1367
- _binaryValue = null ;
1374
+ clearRetainedValues () ;
1368
1375
_tagValues .clear ();
1369
1376
_sharedString = null ;
1370
1377
// completed the whole Object?
@@ -1859,7 +1866,10 @@ public Object getEmbeddedObject() throws JacksonException
1859
1866
if (_tokenIncomplete ) {
1860
1867
_finishToken ();
1861
1868
}
1862
- if (_currToken == JsonToken .VALUE_EMBEDDED_OBJECT ) {
1869
+ if (_currToken == JsonToken .VALUE_EMBEDDED_OBJECT ) {
1870
+ if (_simpleValue != null ) {
1871
+ return _simpleValue ;
1872
+ }
1863
1873
return _binaryValue ;
1864
1874
}
1865
1875
return null ;
@@ -3690,36 +3700,48 @@ protected JsonToken _decodeUndefinedValue() {
3690
3700
* Helper method that deals with details of decoding unallocated "simple values"
3691
3701
* and exposing them as expected token.
3692
3702
* <p>
3693
- * As of Jackson 2.12, simple values are exposed as
3694
- * {@link JsonToken#VALUE_NUMBER_INT}s,
3695
- * but in later versions this is planned to be changed to separate value type.
3703
+ * Starting with Jackson 2.20, this behavior can be changed by enabling the
3704
+ * {@link CBORReadFeature#READ_SIMPLE_VALUE_AS_EMBEDDED_OBJECT}
3705
+ * feature, in which case simple values are returned as {@link JsonToken#VALUE_EMBEDDED_OBJECT} with an
3706
+ * embedded {@link CBORSimpleValue} instance.
3696
3707
*/
3697
3708
public JsonToken _decodeSimpleValue (int lowBits , int ch ) throws JacksonException {
3698
3709
if (lowBits > 24 ) {
3699
3710
_invalidToken (ch );
3700
3711
}
3712
+ final boolean simpleAsEmbedded = CBORReadFeature .READ_SIMPLE_VALUE_AS_EMBEDDED_OBJECT .enabledIn (_formatFeatures );
3701
3713
if (lowBits < 24 ) {
3702
- _numberInt = lowBits ;
3714
+ if (simpleAsEmbedded ) {
3715
+ _simpleValue = new CBORSimpleValue (lowBits );
3716
+ } else {
3717
+ _numberInt = lowBits ;
3718
+ }
3703
3719
} else { // need another byte
3704
3720
if (_inputPtr >= _inputEnd ) {
3705
3721
loadMoreGuaranteed ();
3706
3722
}
3707
- _numberInt = _inputBuffer [ _inputPtr ++] & 0xFF ;
3723
+
3708
3724
// As per CBOR spec, values below 32 not allowed to avoid
3709
3725
// confusion (as well as guarantee uniqueness of encoding)
3710
- if (_numberInt < 32 ) {
3726
+ int value = _inputBuffer [_inputPtr ++] & 0xFF ;
3727
+ if (value < 32 ) {
3711
3728
throw _constructReadException ("Invalid second byte for simple value: 0x"
3712
- +Integer .toHexString (_numberInt )+" (only values 0x20 - 0xFF allowed)" );
3729
+ +Integer .toHexString (value )+" (only values 0x20 - 0xFF allowed)" );
3730
+ }
3731
+
3732
+ if (simpleAsEmbedded ) {
3733
+ _simpleValue = new CBORSimpleValue (value );
3734
+ } else {
3735
+ _numberInt = value ;
3713
3736
}
3714
3737
}
3715
3738
3716
- // 25-Nov-2020, tatu: Although ideally we should report these
3717
- // as `JsonToken.VALUE_EMBEDDED_OBJECT`, due to late addition
3718
- // of handling in 2.12, simple value in 2.12 will be reported
3719
- // as simple ints.
3739
+ if (simpleAsEmbedded ) {
3740
+ return JsonToken .VALUE_EMBEDDED_OBJECT ;
3741
+ }
3720
3742
3721
3743
_numTypesValid = NR_INT ;
3722
- return ( JsonToken .VALUE_NUMBER_INT ) ;
3744
+ return JsonToken .VALUE_NUMBER_INT ;
3723
3745
}
3724
3746
3725
3747
/*
@@ -4080,4 +4102,11 @@ private void createChildObjectContext(final int len) throws JacksonException {
4080
4102
_streamReadContext = _streamReadContext .createChildObjectContext (len );
4081
4103
_streamReadConstraints .validateNestingDepth (_streamReadContext .getNestingDepth ());
4082
4104
}
4105
+
4106
+ // @since 2.20
4107
+ private void clearRetainedValues () {
4108
+ _numTypesValid = NR_UNKNOWN ;
4109
+ _binaryValue = null ;
4110
+ _simpleValue = null ;
4111
+ }
4083
4112
}
0 commit comments