@@ -111,7 +111,11 @@ public static async Task<DecodeResult> DecodeAsync(
111111 ArrayPool < byte > ? arrayPool ,
112112 CancellationToken cancellationToken )
113113 {
114+ var growBuffer = arrayPool != null ;
114115 var isRentedBuffer = false ;
116+
117+ arrayPool ??= ArrayPool < byte > . Shared ;
118+
115119 if ( buffer == null )
116120 {
117121 if ( arrayPool == null )
@@ -151,9 +155,10 @@ public static async Task<DecodeResult> DecodeAsync(
151155 var jsonReader = new Utf8JsonReader ( readerBuffer , isCompleted , readerState ) ;
152156
153157 var status = DecodeCore (
158+ arrayPool ,
154159 ref frames ,
155160 ref buffer ,
156- arrayPool ,
161+ growBuffer ,
157162 ref isRentedBuffer ,
158163 ref position ,
159164 ref jsonReader ) ;
@@ -199,7 +204,11 @@ private static (byte[] Buffer, int Position) DecodeImpl(
199204 ReadOnlySpan < byte > utf8Json ,
200205 ArrayPool < byte > ? arrayPool )
201206 {
207+ var growBuffer = arrayPool != null ;
202208 var isRentedBuffer = false ;
209+
210+ arrayPool ??= ArrayPool < byte > . Shared ;
211+
203212 if ( buffer == null )
204213 {
205214 if ( arrayPool == null )
@@ -215,10 +224,10 @@ private static (byte[] Buffer, int Position) DecodeImpl(
215224
216225 do
217226 {
218- var status = DecodeCore (
227+ var status = DecodeCore ( arrayPool ,
219228 ref frames ,
220229 ref buffer ,
221- arrayPool ,
230+ growBuffer ,
222231 ref isRentedBuffer ,
223232 ref position ,
224233 ref jsonReader ) ;
@@ -234,9 +243,10 @@ private static (byte[] Buffer, int Position) DecodeImpl(
234243 }
235244
236245 private static Lite3 . Status DecodeCore (
246+ ArrayPool < byte > arrayPool ,
237247 ref FrameStack frames ,
238248 ref byte [ ] buffer ,
239- ArrayPool < byte > ? arrayPool ,
249+ bool growBuffer ,
240250 ref bool isRentedBuffer ,
241251 ref int position ,
242252 ref Utf8JsonReader reader )
@@ -252,16 +262,16 @@ private static Lite3.Status DecodeCore(
252262
253263 var status = frame . Kind switch
254264 {
255- FrameKind . Object => DecodeObject ( ref frames , replayToken , ref reader ) ,
256- FrameKind . ObjectSwitch => DecodeObjectSwitch ( ref frames , buffer , ref position , replayToken , ref reader ) ,
257- FrameKind . Array => DecodeArray ( ref frames , replayToken , ref reader ) ,
258- FrameKind . ArraySwitch => DecodeArraySwitch ( ref frames , buffer , ref position , ref reader ) ,
265+ FrameKind . Object => DecodeObject ( arrayPool , ref frames , replayToken , ref reader ) ,
266+ FrameKind . ObjectSwitch => DecodeObjectSwitch ( arrayPool , ref frames , buffer , ref position , replayToken , ref reader ) ,
267+ FrameKind . Array => DecodeArray ( arrayPool , ref frames , replayToken , ref reader ) ,
268+ FrameKind . ArraySwitch => DecodeArraySwitch ( arrayPool , ref frames , buffer , ref position , ref reader ) ,
259269 _ => throw new InvalidDataException ( "Unknown frame kind." )
260270 } ;
261271
262272 replayToken = false ;
263273
264- if ( status == Lite3 . Status . InsufficientBuffer && arrayPool != null )
274+ if ( status == Lite3 . Status . InsufficientBuffer && growBuffer )
265275 {
266276 status = TronBuffer . Grow ( arrayPool , isRentedBuffer , buffer , out buffer ) ;
267277 isRentedBuffer = true ;
@@ -307,6 +317,7 @@ private static Lite3.Status DecodeDocument(
307317 }
308318
309319 private static Lite3 . Status DecodeObject (
320+ ArrayPool < byte > arrayPool ,
310321 ref FrameStack frames ,
311322 bool replayToken ,
312323 ref Utf8JsonReader reader )
@@ -323,21 +334,22 @@ private static Lite3.Status DecodeObject(
323334 {
324335 if ( reader . TokenType == JsonTokenType . EndObject )
325336 {
326- frames . Pop ( ) ;
337+ frames . Pop ( arrayPool ) ;
327338 return 0 ;
328339 }
329340
330341 if ( reader . TokenType != JsonTokenType . PropertyName )
331342 return Lite3 . Status . ExpectedJsonProperty ;
332343
333- frames . Push ( Frame . ForObjectSwitch ( offset , GetKeyRef ( ref reader ) ) ) ;
344+ frames . Push ( Frame . ForObjectSwitch ( offset , GetKeyRef ( arrayPool , ref reader ) ) ) ;
334345 return 0 ;
335346 }
336347
337348 return reader . IsFinalBlock ? Lite3 . Status . InsufficientBuffer : Lite3 . Status . NeedsMoreData ;
338349 }
339350
340351 private static Lite3 . Status DecodeObjectSwitch (
352+ ArrayPool < byte > arrayPool ,
341353 ref FrameStack frames ,
342354 byte [ ] buffer ,
343355 ref int position ,
@@ -377,17 +389,17 @@ private static Lite3.Status DecodeObjectSwitch(
377389 }
378390 case JsonTokenType . String :
379391 {
380- var value = ReadUtf8Value ( ref reader , out var rentedBuffer ) ;
392+ var value = ReadUtf8Value ( arrayPool , ref reader , out var rentedBuffer ) ;
381393 status = Lite3 . SetString ( buffer , ref position , offset , key , keyData , value ) ;
382394 if ( rentedBuffer != null )
383- ArrayPool < byte > . Shared . Return ( rentedBuffer ) ;
395+ arrayPool . Return ( rentedBuffer ) ;
384396 break ;
385397 }
386398 case JsonTokenType . StartObject :
387399 {
388400 if ( ( status = Lite3 . SetObject ( buffer , ref position , offset , key , keyData , out var objectOffset ) ) >= 0 )
389401 {
390- frames . Pop ( ) ;
402+ frames . Pop ( arrayPool ) ;
391403 frames . Push ( Frame . ForObject ( objectOffset ) ) ;
392404 }
393405
@@ -397,7 +409,7 @@ private static Lite3.Status DecodeObjectSwitch(
397409 {
398410 if ( ( status = Lite3 . SetArray ( buffer , ref position , offset , key , keyData , out var arrayOffset ) ) >= 0 )
399411 {
400- frames . Pop ( ) ;
412+ frames . Pop ( arrayPool ) ;
401413 frames . Push ( Frame . ForArray ( arrayOffset ) ) ;
402414 }
403415
@@ -411,12 +423,16 @@ private static Lite3.Status DecodeObjectSwitch(
411423 if ( status < 0 )
412424 return status ;
413425
414- frames . Pop ( ) ;
426+ frames . Pop ( arrayPool ) ;
415427
416428 return status ;
417429 }
418430
419- private static Lite3 . Status DecodeArray ( ref FrameStack frames , bool replayToken , ref Utf8JsonReader reader )
431+ private static Lite3 . Status DecodeArray (
432+ ArrayPool < byte > arrayPool ,
433+ ref FrameStack frames ,
434+ bool replayToken ,
435+ ref Utf8JsonReader reader )
420436 {
421437 if ( reader . CurrentDepth > JsonConstants . NestingDepthMax )
422438 return Lite3 . Status . JsonNestingDepthExceededMax ;
@@ -430,7 +446,7 @@ private static Lite3.Status DecodeArray(ref FrameStack frames, bool replayToken,
430446 {
431447 if ( reader . TokenType == JsonTokenType . EndArray )
432448 {
433- frames . Pop ( ) ;
449+ frames . Pop ( arrayPool ) ;
434450 return 0 ;
435451 }
436452
@@ -442,6 +458,7 @@ private static Lite3.Status DecodeArray(ref FrameStack frames, bool replayToken,
442458 }
443459
444460 private static Lite3 . Status DecodeArraySwitch (
461+ ArrayPool < byte > arrayPool ,
445462 ref FrameStack frames ,
446463 byte [ ] buffer ,
447464 ref int position ,
@@ -474,17 +491,17 @@ private static Lite3.Status DecodeArraySwitch(
474491 }
475492 case JsonTokenType . String :
476493 {
477- var value = ReadUtf8Value ( ref reader , out var rentedBuffer ) ;
494+ var value = ReadUtf8Value ( arrayPool , ref reader , out var rentedBuffer ) ;
478495 status = Lite3 . ArrayAppendString ( buffer , ref position , offset , value ) ;
479496 if ( rentedBuffer != null )
480- ArrayPool < byte > . Shared . Return ( rentedBuffer ) ;
497+ arrayPool . Return ( rentedBuffer ) ;
481498 break ;
482499 }
483500 case JsonTokenType . StartObject :
484501 {
485502 if ( ( status = Lite3 . ArrayAppendObject ( buffer , ref position , offset , out var objectOffset ) ) >= 0 )
486503 {
487- frames . Pop ( ) ;
504+ frames . Pop ( arrayPool ) ;
488505 frames . Push ( Frame . ForObject ( objectOffset ) ) ;
489506 }
490507
@@ -494,7 +511,7 @@ private static Lite3.Status DecodeArraySwitch(
494511 {
495512 if ( ( status = Lite3 . ArrayAppendArray ( buffer , ref position , offset , out var arrayOffset ) ) >= 0 )
496513 {
497- frames . Pop ( ) ;
514+ frames . Pop ( arrayPool ) ;
498515 frames . Push ( Frame . ForArray ( arrayOffset ) ) ;
499516 }
500517
@@ -505,12 +522,12 @@ private static Lite3.Status DecodeArraySwitch(
505522 break ;
506523 }
507524
508- frames . Pop ( ) ;
525+ frames . Pop ( arrayPool ) ;
509526
510527 return status ;
511528 }
512529
513- private static KeyRef GetKeyRef ( ref Utf8JsonReader reader )
530+ private static KeyRef GetKeyRef ( ArrayPool < byte > arrayPool , ref Utf8JsonReader reader )
514531 {
515532 var length = reader . HasValueSequence
516533 ? checked ( ( int ) reader . ValueSequence . Length )
@@ -530,7 +547,7 @@ private static KeyRef GetKeyRef(ref Utf8JsonReader reader)
530547 } ;
531548 }
532549
533- var pooledKey = ArrayPool < byte > . Shared . Rent ( length ) ;
550+ var pooledKey = arrayPool . Rent ( length ) ;
534551
535552 length = reader . CopyString ( pooledKey ) ;
536553
@@ -543,15 +560,18 @@ private static KeyRef GetKeyRef(ref Utf8JsonReader reader)
543560 }
544561
545562 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
546- private static ReadOnlySpan < byte > ReadUtf8Value ( ref Utf8JsonReader reader , out byte [ ] ? rented )
563+ private static ReadOnlySpan < byte > ReadUtf8Value (
564+ ArrayPool < byte > arrayPool ,
565+ ref Utf8JsonReader reader ,
566+ out byte [ ] ? rented )
547567 {
548568 if ( reader . HasValueSequence || reader . ValueIsEscaped )
549569 {
550570 var length = reader . HasValueSequence
551571 ? checked ( ( int ) reader . ValueSequence . Length )
552572 : reader . ValueSpan . Length ;
553573
554- rented = ArrayPool < byte > . Shared . Rent ( length ) ;
574+ rented = arrayPool . Rent ( length ) ;
555575 length = reader . CopyString ( rented ) ;
556576
557577 return rented . AsSpan ( 0 , length ) ;
@@ -582,12 +602,12 @@ public Lite3.Status Push(in Frame frame)
582602 }
583603
584604 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
585- public void Pop ( )
605+ public void Pop ( ArrayPool < byte > arrayPool )
586606 {
587607 ref var frame = ref _frames [ _index ] ;
588608
589609 if ( frame is { Kind : FrameKind . ObjectSwitch } )
590- frame . KeyRef . Return ( ) ;
610+ frame . KeyRef . Return ( arrayPool ) ;
591611
592612 _frames [ _index -- ] = default ;
593613 }
@@ -643,10 +663,10 @@ private struct KeyRef
643663 } ;
644664
645665 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
646- public void Return ( )
666+ public void Return ( ArrayPool < byte > arrayPool )
647667 {
648668 if ( Kind == KeyRefKind . Pooled && PooledKey != null )
649- ArrayPool < byte > . Shared . Return ( PooledKey ) ;
669+ arrayPool . Return ( PooledKey ) ;
650670 }
651671 }
652672
0 commit comments