Skip to content

Commit a42ac91

Browse files
[Json] Avoid ReadOnlySequence with Stream deserializing (#118408)
1 parent 386cb8d commit a42ac91

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IReadBufferState.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ internal interface IReadBufferState<TReadBufferState, TStream> : IDisposable
1212
{
1313
public abstract bool IsFinalBlock { get; }
1414

15+
#if DEBUG
16+
// Used for Debug.Assert's
1517
public abstract ReadOnlySequence<byte> Bytes { get; }
18+
#endif
1619

1720
public abstract ValueTask<TReadBufferState> ReadAsync(
1821
TStream utf8Json,
@@ -22,5 +25,7 @@ public abstract ValueTask<TReadBufferState> ReadAsync(
2225
public abstract void Read(TStream utf8Json);
2326

2427
public abstract void Advance(long bytesConsumed);
28+
29+
public abstract Utf8JsonReader GetReader(JsonReaderState jsonReaderState);
2530
}
2631
}

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,29 +136,17 @@ internal bool ContinueDeserialize<TReadBufferState, TStream>(
136136
out T? value)
137137
where TReadBufferState : struct, IReadBufferState<TReadBufferState, TStream>
138138
{
139-
Utf8JsonReader reader;
140-
if (bufferState.Bytes.IsSingleSegment)
141-
{
142-
reader = new Utf8JsonReader(
143-
#if NET
144-
bufferState.Bytes.FirstSpan,
145-
#else
146-
bufferState.Bytes.First.Span,
147-
#endif
148-
bufferState.IsFinalBlock, jsonReaderState);
149-
}
150-
else
151-
{
152-
reader = new Utf8JsonReader(bufferState.Bytes, bufferState.IsFinalBlock, jsonReaderState);
153-
}
139+
Utf8JsonReader reader = bufferState.GetReader(jsonReaderState);
154140

155141
try
156142
{
157143
bool success = EffectiveConverter.ReadCore(ref reader, out value, Options, ref readStack);
158144

145+
#if DEBUG
159146
Debug.Assert(reader.BytesConsumed <= bufferState.Bytes.Length);
160147
Debug.Assert(!bufferState.IsFinalBlock || reader.AllowMultipleValues || reader.BytesConsumed == bufferState.Bytes.Length,
161148
"The reader should have thrown if we have remaining bytes.");
149+
#endif
162150

163151
jsonReaderState = reader.CurrentState;
164152
return success;

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PipeReadBufferState.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ public PipeReadBufferState(PipeReader utf8Json)
2727

2828
public readonly bool IsFinalBlock => _isFinalBlock;
2929

30+
#if DEBUG
3031
public readonly ReadOnlySequence<byte> Bytes => _sequence;
32+
#endif
3133

3234
public void Advance(long bytesConsumed)
3335
{
@@ -73,6 +75,24 @@ public async ValueTask<PipeReadBufferState> ReadAsync(PipeReader utf8Json, Cance
7375

7476
public void Read(PipeReader utf8Json) => throw new NotImplementedException();
7577

78+
public Utf8JsonReader GetReader(JsonReaderState jsonReaderState)
79+
{
80+
if (_sequence.IsSingleSegment)
81+
{
82+
return new Utf8JsonReader(
83+
#if NET
84+
_sequence.FirstSpan,
85+
#else
86+
_sequence.First.Span,
87+
#endif
88+
IsFinalBlock, jsonReaderState);
89+
}
90+
else
91+
{
92+
return new Utf8JsonReader(_sequence, IsFinalBlock, jsonReaderState);
93+
}
94+
}
95+
7696
private void ProcessReadBytes()
7797
{
7898
if (_isFirstBlock)

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/StreamReadBufferState.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ public StreamReadBufferState(int initialBufferSize)
5151

5252
public readonly bool IsFinalBlock => _isFinalBlock;
5353

54+
#if DEBUG
5455
public readonly ReadOnlySequence<byte> Bytes => new(_buffer.AsMemory(_offset, _count));
56+
#endif
5557

5658
/// <summary>
5759
/// Read from the stream until either our buffer is filled or we hit EOF.
@@ -155,6 +157,14 @@ public void Advance(long bytesConsumed)
155157
_offset = 0;
156158
}
157159

160+
public Utf8JsonReader GetReader(JsonReaderState jsonReaderState)
161+
{
162+
return new Utf8JsonReader(
163+
_buffer.AsSpan(_offset, _count),
164+
IsFinalBlock,
165+
jsonReaderState);
166+
}
167+
158168
private void ProcessReadBytes()
159169
{
160170
if (_count > _maxCount)

0 commit comments

Comments
 (0)