17
17
package org .springframework .http .codec .json ;
18
18
19
19
import java .io .IOException ;
20
+ import java .nio .ByteBuffer ;
20
21
import java .util .ArrayList ;
21
22
import java .util .List ;
22
23
import java .util .function .Function ;
26
27
import com .fasterxml .jackson .core .JsonProcessingException ;
27
28
import com .fasterxml .jackson .core .JsonToken ;
28
29
import com .fasterxml .jackson .core .async .ByteArrayFeeder ;
30
+ import com .fasterxml .jackson .core .async .ByteBufferFeeder ;
31
+ import com .fasterxml .jackson .core .async .NonBlockingInputFeeder ;
29
32
import com .fasterxml .jackson .databind .DeserializationContext ;
30
33
import com .fasterxml .jackson .databind .ObjectMapper ;
31
34
import com .fasterxml .jackson .databind .deser .DefaultDeserializationContext ;
32
35
import com .fasterxml .jackson .databind .util .TokenBuffer ;
36
+ import com .fasterxml .jackson .dataformat .smile .SmileFactory ;
33
37
import reactor .core .Exceptions ;
34
38
import reactor .core .publisher .Flux ;
35
39
@@ -54,6 +58,8 @@ final class Jackson2Tokenizer {
54
58
55
59
private final DeserializationContext deserializationContext ;
56
60
61
+ private final NonBlockingInputFeeder inputFeeder ;
62
+
57
63
private final boolean tokenizeArrayElements ;
58
64
59
65
private final boolean forceUseOfBigDecimal ;
@@ -69,33 +75,32 @@ final class Jackson2Tokenizer {
69
75
private TokenBuffer tokenBuffer ;
70
76
71
77
72
- // TODO: change to ByteBufferFeeder when supported by Jackson
73
- // See https://github.com/FasterXML/jackson-core/issues/478
74
- private final ByteArrayFeeder inputFeeder ;
75
-
76
-
77
78
private Jackson2Tokenizer (JsonParser parser , DeserializationContext deserializationContext ,
78
79
boolean tokenizeArrayElements , boolean forceUseOfBigDecimal , int maxInMemorySize ) {
79
80
80
81
this .parser = parser ;
81
82
this .deserializationContext = deserializationContext ;
83
+ this .inputFeeder = this .parser .getNonBlockingInputFeeder ();
82
84
this .tokenizeArrayElements = tokenizeArrayElements ;
83
85
this .forceUseOfBigDecimal = forceUseOfBigDecimal ;
84
- this .inputFeeder = (ByteArrayFeeder ) this .parser .getNonBlockingInputFeeder ();
85
86
this .maxInMemorySize = maxInMemorySize ;
86
87
this .tokenBuffer = createToken ();
87
88
}
88
89
89
90
90
91
91
92
private List <TokenBuffer > tokenize (DataBuffer dataBuffer ) {
92
- int bufferSize = dataBuffer .readableByteCount ();
93
- byte [] bytes = new byte [bufferSize ];
94
- dataBuffer .read (bytes );
95
- DataBufferUtils .release (dataBuffer );
96
-
97
93
try {
98
- this .inputFeeder .feedInput (bytes , 0 , bytes .length );
94
+ int bufferSize = dataBuffer .readableByteCount ();
95
+ if (this .inputFeeder instanceof ByteBufferFeeder byteBufferFeeder ) {
96
+ ByteBuffer byteBuffer = dataBuffer .toByteBuffer ();
97
+ byteBufferFeeder .feedInput (byteBuffer );
98
+ }
99
+ else if (this .inputFeeder instanceof ByteArrayFeeder byteArrayFeeder ) {
100
+ byte [] bytes = new byte [bufferSize ];
101
+ dataBuffer .read (bytes );
102
+ byteArrayFeeder .feedInput (bytes , 0 , bufferSize );
103
+ }
99
104
List <TokenBuffer > result = parseTokenBufferFlux ();
100
105
assertInMemorySize (bufferSize , result );
101
106
return result ;
@@ -106,6 +111,9 @@ private List<TokenBuffer> tokenize(DataBuffer dataBuffer) {
106
111
catch (IOException ex ) {
107
112
throw Exceptions .propagate (ex );
108
113
}
114
+ finally {
115
+ DataBufferUtils .release (dataBuffer );
116
+ }
109
117
}
110
118
111
119
private Flux <TokenBuffer > endOfInput () {
@@ -232,7 +240,14 @@ public static Flux<TokenBuffer> tokenize(Flux<DataBuffer> dataBuffers, JsonFacto
232
240
ObjectMapper objectMapper , boolean tokenizeArrays , boolean forceUseOfBigDecimal , int maxInMemorySize ) {
233
241
234
242
try {
235
- JsonParser parser = jsonFactory .createNonBlockingByteArrayParser ();
243
+ JsonParser parser ;
244
+ if (jsonFactory .getFormatName ().equals (SmileFactory .FORMAT_NAME_SMILE )) {
245
+ // ByteBufferFeeder is not supported for Smile
246
+ parser = jsonFactory .createNonBlockingByteArrayParser ();
247
+ }
248
+ else {
249
+ parser = jsonFactory .createNonBlockingByteBufferParser ();
250
+ }
236
251
DeserializationContext context = objectMapper .getDeserializationContext ();
237
252
if (context instanceof DefaultDeserializationContext ) {
238
253
context = ((DefaultDeserializationContext ) context ).createInstance (
0 commit comments