20
20
public final class CBORParser extends ParserMinimalBase
21
21
{
22
22
private final static byte [] NO_BYTES = new byte [0 ];
23
-
23
+
24
24
/**
25
25
* Enumeration that defines all togglable features for CBOR generators.
26
26
*/
@@ -66,13 +66,13 @@ private Feature(boolean defaultState) {
66
66
// Constants for handling of 16-bit "mini-floats"
67
67
private final static double MATH_POW_2_10 = Math .pow (2 , 10 );
68
68
private final static double MATH_POW_2_NEG14 = Math .pow (2 , -14 );
69
-
69
+
70
70
/*
71
71
/**********************************************************
72
72
/* Configuration
73
73
/**********************************************************
74
74
*/
75
-
75
+
76
76
/**
77
77
* Codec used for data binding when (if) requested.
78
78
*/
@@ -167,7 +167,7 @@ private Feature(boolean defaultState) {
167
167
* in the end it'll be converted to 1-based)
168
168
*/
169
169
protected int _tokenInputCol = 0 ;
170
-
170
+
171
171
/*
172
172
/**********************************************************
173
173
/* Parsing state
@@ -179,6 +179,7 @@ private Feature(boolean defaultState) {
179
179
* the next token is to be parsed (root, array, object).
180
180
*/
181
181
protected CBORReadContext _parsingContext ;
182
+
182
183
/**
183
184
* Buffer that contains contents of String values, including
184
185
* field names if necessary (name split across boundary,
@@ -199,7 +200,7 @@ private Feature(boolean defaultState) {
199
200
* representation being available via read context)
200
201
*/
201
202
protected boolean _nameCopied = false ;
202
-
203
+
203
204
/**
204
205
* ByteArrayBuilder is needed if 'getBinaryValue' is called. If so,
205
206
* we better reuse it for remainder of content.
@@ -247,7 +248,7 @@ private Feature(boolean defaultState) {
247
248
* buffer.
248
249
*/
249
250
protected boolean _bufferRecyclable ;
250
-
251
+
251
252
/*
252
253
/**********************************************************
253
254
/* Additional parsing state
@@ -372,7 +373,7 @@ private Feature(boolean defaultState) {
372
373
/* Life-cycle
373
374
/**********************************************************
374
375
*/
375
-
376
+
376
377
public CBORParser (IOContext ctxt , int parserFeatures , int cborFeatures ,
377
378
ObjectCodec codec , ByteQuadsCanonicalizer sym ,
378
379
InputStream in , byte [] inputBuffer , int start , int end ,
@@ -423,7 +424,7 @@ public Version version() {
423
424
/* Configuration
424
425
/**********************************************************
425
426
*/
426
-
427
+
427
428
// public JsonParser overrideStdFeatures(int values, int mask)
428
429
429
430
@ Override
@@ -675,11 +676,30 @@ public JsonToken nextToken() throws IOException
675
676
_numberInt = _decode16Bits ();
676
677
break ;
677
678
case 2 :
678
- _numberInt = _decode32Bits ();
679
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
680
+ {
681
+ int v = _decode32Bits ();
682
+ if (v >= 0 ) {
683
+ _numberInt = v ;
684
+ } else {
685
+ long l = (long ) v ;
686
+ _numberLong = l & 0xFFFFFFFFL ;
687
+ _numTypesValid = NR_LONG ;
688
+ }
689
+ }
679
690
break ;
680
691
case 3 :
681
- _numberLong = _decode64Bits ();
682
- _numTypesValid = NR_LONG ;
692
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
693
+ {
694
+ long l = _decode64Bits ();
695
+ if (l >= 0L ) {
696
+ _numberLong = l ;
697
+ _numTypesValid = NR_LONG ;
698
+ } else {
699
+ _numberBigInt = _bigPositive (l );
700
+ _numTypesValid = NR_BIGINT ;
701
+ }
702
+ }
683
703
break ;
684
704
default :
685
705
_invalidToken (ch );
@@ -699,11 +719,29 @@ public JsonToken nextToken() throws IOException
699
719
_numberInt = -_decode16Bits () - 1 ;
700
720
break ;
701
721
case 2 :
702
- _numberInt = -_decode32Bits () - 1 ;
722
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
723
+ {
724
+ int v = _decode32Bits ();
725
+ if (v < 0 ) {
726
+ _numberLong = ((long ) v ) + -1L ;
727
+ _numTypesValid = NR_LONG ;
728
+ } else {
729
+ _numberInt = -v - 1 ;
730
+ }
731
+ }
703
732
break ;
704
733
case 3 :
705
- _numberLong = -_decode64Bits () - 1L ;
706
- _numTypesValid = NR_LONG ;
734
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
735
+ {
736
+ long l = _decode64Bits ();
737
+ if (l >= 0L ) {
738
+ _numberLong = -l - 1L ;
739
+ _numTypesValid = NR_LONG ;
740
+ } else {
741
+ _numberBigInt = _bigNegative (l );
742
+ _numTypesValid = NR_BIGINT ;
743
+ }
744
+ }
707
745
break ;
708
746
default :
709
747
_invalidToken (ch );
@@ -784,7 +822,7 @@ public JsonToken nextToken() throws IOException
784
822
}
785
823
return null ;
786
824
}
787
-
825
+
788
826
protected String _numberToName (int ch , boolean neg ) throws IOException
789
827
{
790
828
final int lowBits = ch & 0x1F ;
@@ -1109,11 +1147,30 @@ public String nextTextValue() throws IOException
1109
1147
_numberInt = _decode16Bits ();
1110
1148
break ;
1111
1149
case 2 :
1112
- _numberInt = _decode32Bits ();
1150
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
1151
+ {
1152
+ int v = _decode32Bits ();
1153
+ if (v < 0 ) {
1154
+ long l = (long ) v ;
1155
+ _numberLong = l & 0xFFFFFFFFL ;
1156
+ _numTypesValid = NR_LONG ;
1157
+ } else {
1158
+ _numberInt = v ;
1159
+ }
1160
+ }
1113
1161
break ;
1114
1162
case 3 :
1115
- _numberLong = _decode64Bits ();
1116
- _numTypesValid = NR_LONG ;
1163
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
1164
+ {
1165
+ long l = _decode64Bits ();
1166
+ if (l >= 0L ) {
1167
+ _numberLong = l ;
1168
+ _numTypesValid = NR_LONG ;
1169
+ } else {
1170
+ _numberBigInt = _bigPositive (l );
1171
+ _numTypesValid = NR_BIGINT ;
1172
+ }
1173
+ }
1117
1174
break ;
1118
1175
default :
1119
1176
_invalidToken (ch );
@@ -1134,11 +1191,29 @@ public String nextTextValue() throws IOException
1134
1191
_numberInt = -_decode16Bits () - 1 ;
1135
1192
break ;
1136
1193
case 2 :
1137
- _numberInt = -_decode32Bits () - 1 ;
1194
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
1195
+ {
1196
+ int v = _decode32Bits ();
1197
+ if (v < 0 ) {
1198
+ _numberLong = ((long ) v ) + -1L ;
1199
+ _numTypesValid = NR_LONG ;
1200
+ } else {
1201
+ _numberInt = -v - 1 ;
1202
+ }
1203
+ }
1138
1204
break ;
1139
1205
case 3 :
1140
- _numberLong = -_decode64Bits () - 1L ;
1141
- _numTypesValid = NR_LONG ;
1206
+ // 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
1207
+ {
1208
+ long l = _decode64Bits ();
1209
+ if (l >= 0L ) {
1210
+ _numberLong = l ;
1211
+ _numTypesValid = NR_LONG ;
1212
+ } else {
1213
+ _numberBigInt = _bigNegative (l );
1214
+ _numTypesValid = NR_BIGINT ;
1215
+ }
1216
+ }
1142
1217
break ;
1143
1218
default :
1144
1219
_invalidToken (ch );
@@ -3081,5 +3156,21 @@ protected void _reportInvalidOther(int mask, int ptr) throws JsonParseException
3081
3156
_inputPtr = ptr ;
3082
3157
_reportInvalidOther (mask );
3083
3158
}
3159
+
3160
+ /*
3161
+ /**********************************************************
3162
+ /* Internal methods, other
3163
+ /**********************************************************
3164
+ */
3165
+
3166
+ private final static BigInteger BIT_63 = BigInteger .ONE .shiftLeft (63 );
3167
+
3168
+ private final BigInteger _bigPositive (long l ) {
3169
+ BigInteger biggie = BigInteger .valueOf ((l << 1 ) >>> 1 );
3170
+ return biggie .or (BIT_63 );
3171
+ }
3172
+
3173
+ private final BigInteger _bigNegative (long l ) {
3174
+ return BigInteger .valueOf (l ).subtract (BigInteger .ONE );
3175
+ }
3084
3176
}
3085
-
0 commit comments