47
47
public class MessagePackParser
48
48
extends ParserMinimalBase
49
49
{
50
- private static final ThreadLocal <Tuple <Object , MessageUnpacker >> messageUnpackerHolder =
51
- new ThreadLocal <Tuple < Object , MessageUnpacker > >();
50
+ private static final ThreadLocal <Triple <Object , MessageUnpacker , MessageBufferInputLocator >> reuseObjectHolder =
51
+ new ThreadLocal <>();
52
52
private final MessageUnpacker messageUnpacker ;
53
53
54
54
private static final BigInteger LONG_MIN = BigInteger .valueOf ((long ) Long .MIN_VALUE );
@@ -126,11 +126,17 @@ public MessagePackParser(
126
126
IOContext ctxt ,
127
127
int features ,
128
128
ObjectCodec objectCodec ,
129
- InputStream in ,
129
+ final InputStream in ,
130
130
boolean reuseResourceInParser )
131
131
throws IOException
132
132
{
133
- this (ctxt , features , new InputStreamBufferInput (in ), objectCodec , in , reuseResourceInParser );
133
+ this (ctxt , features , new MessageBufferInputProvider () {
134
+ @ Override
135
+ public MessageBufferInput provide ()
136
+ {
137
+ return new InputStreamBufferInput (in );
138
+ }
139
+ }, objectCodec , in , reuseResourceInParser );
134
140
}
135
141
136
142
public MessagePackParser (IOContext ctxt , int features , ObjectCodec objectCodec , byte [] bytes )
@@ -143,16 +149,22 @@ public MessagePackParser(
143
149
IOContext ctxt ,
144
150
int features ,
145
151
ObjectCodec objectCodec ,
146
- byte [] bytes ,
152
+ final byte [] bytes ,
147
153
boolean reuseResourceInParser )
148
154
throws IOException
149
155
{
150
- this (ctxt , features , new ArrayBufferInput (bytes ), objectCodec , bytes , reuseResourceInParser );
156
+ this (ctxt , features , new MessageBufferInputProvider () {
157
+ @ Override
158
+ public MessageBufferInput provide ()
159
+ {
160
+ return new ArrayBufferInput (bytes );
161
+ }
162
+ }, objectCodec , bytes , reuseResourceInParser );
151
163
}
152
164
153
165
private MessagePackParser (IOContext ctxt ,
154
166
int features ,
155
- MessageBufferInput input ,
167
+ MessageBufferInputProvider bufferInputProvider ,
156
168
ObjectCodec objectCodec ,
157
169
Object src ,
158
170
boolean reuseResourceInParser )
@@ -167,29 +179,48 @@ private MessagePackParser(IOContext ctxt,
167
179
parsingContext = JsonReadContext .createRootContext (dups );
168
180
this .reuseResourceInParser = reuseResourceInParser ;
169
181
if (!reuseResourceInParser ) {
170
- this .messageUnpacker = MessagePack .newDefaultUnpacker (input );
182
+ this .messageUnpacker = MessagePack .newDefaultUnpacker (bufferInputProvider . provide () );
171
183
return ;
172
184
}
173
185
else {
174
186
this .messageUnpacker = null ;
175
187
}
176
188
177
189
MessageUnpacker messageUnpacker ;
178
- Tuple <Object , MessageUnpacker > messageUnpackerTuple = messageUnpackerHolder .get ();
179
- if (messageUnpackerTuple == null ) {
180
- messageUnpacker = MessagePack .newDefaultUnpacker (input );
190
+ MessageBufferInputLocator messageBufferInputLocator ;
191
+ Triple <Object , MessageUnpacker , MessageBufferInputLocator > messageUnpackerTriple = reuseObjectHolder .get ();
192
+ if (messageUnpackerTriple == null ) {
193
+ final MessageBufferInputRegistry messageBufferInputRegistry = new MessageBufferInputRegistry ();
194
+ messageBufferInputRegistry .register (src .getClass (), bufferInputProvider );
195
+ messageBufferInputLocator = messageBufferInputRegistry ;
196
+ messageUnpacker = MessagePack .newDefaultUnpacker (messageBufferInputRegistry .get (src .getClass ()));
181
197
}
182
198
else {
183
199
// Considering to reuse InputStream with JsonParser.Feature.AUTO_CLOSE_SOURCE,
184
200
// MessagePackParser needs to use the MessageUnpacker that has the same InputStream
185
201
// since it has buffer which has loaded the InputStream data ahead.
186
202
// However, it needs to call MessageUnpacker#reset when the source is different from the previous one.
187
- if (isEnabled (JsonParser .Feature .AUTO_CLOSE_SOURCE ) || messageUnpackerTuple .first () != src ) {
188
- messageUnpackerTuple .second ().reset (input );
203
+ if (isEnabled (JsonParser .Feature .AUTO_CLOSE_SOURCE ) || messageUnpackerTriple .first () != src ) {
204
+ final MessageBufferInputLocator bufferInputLocator = messageUnpackerTriple .third ();
205
+ MessageBufferInput messageBufferInput = bufferInputLocator .get (src .getClass ());
206
+ if (messageBufferInput != null ) {
207
+ messageBufferInput .reset (src );
208
+ }
209
+ else {
210
+ if (bufferInputLocator instanceof MessageBufferInputRegistry ) {
211
+ ((MessageBufferInputRegistry ) bufferInputLocator ).register (src .getClass (), bufferInputProvider );
212
+ messageBufferInput = bufferInputLocator .get (src .getClass ());
213
+ }
214
+ else {
215
+ messageBufferInput = bufferInputProvider .provide ();
216
+ }
217
+ }
218
+ messageUnpackerTriple .second ().reset (messageBufferInput );
189
219
}
190
- messageUnpacker = messageUnpackerTuple .second ();
220
+ messageUnpacker = messageUnpackerTriple .second ();
221
+ messageBufferInputLocator = messageUnpackerTriple .third ();
191
222
}
192
- messageUnpackerHolder .set (new Tuple <Object , MessageUnpacker >(src , messageUnpacker ));
223
+ reuseObjectHolder .set (new Triple <Object , MessageUnpacker , MessageBufferInputLocator >(src , messageUnpacker , messageBufferInputLocator ));
193
224
}
194
225
195
226
public void setExtensionTypeCustomDeserializers (ExtensionTypeCustomDeserializers extTypeCustomDesers )
@@ -690,7 +721,7 @@ private MessageUnpacker getMessageUnpacker()
690
721
return this .messageUnpacker ;
691
722
}
692
723
693
- Tuple <Object , MessageUnpacker > messageUnpackerTuple = messageUnpackerHolder .get ();
724
+ Triple <Object , MessageUnpacker , MessageBufferInputLocator > messageUnpackerTuple = reuseObjectHolder .get ();
694
725
if (messageUnpackerTuple == null ) {
695
726
throw new IllegalStateException ("messageUnpacker is null" );
696
727
}
0 commit comments