1
1
// Copyright (c) Six Labors.
2
2
// Licensed under the Six Labors Split License.
3
- #nullable disable
4
3
5
4
using System . Buffers ;
6
5
using System . Runtime . CompilerServices ;
@@ -19,7 +18,7 @@ internal sealed class ChunkedMemoryStream : Stream
19
18
private readonly MemoryAllocator allocator ;
20
19
21
20
// Data
22
- private MemoryChunk memoryChunk ;
21
+ private MemoryChunk ? memoryChunk ;
23
22
24
23
// The total number of allocated chunks
25
24
private int chunkCount ;
@@ -31,13 +30,13 @@ internal sealed class ChunkedMemoryStream : Stream
31
30
private bool isDisposed ;
32
31
33
32
// Current chunk to write to
34
- private MemoryChunk writeChunk ;
33
+ private MemoryChunk ? writeChunk ;
35
34
36
35
// Offset into chunk to write to
37
36
private int writeOffset ;
38
37
39
38
// Current chunk to read from
40
- private MemoryChunk readChunk ;
39
+ private MemoryChunk ? readChunk ;
41
40
42
41
// Offset into chunk to read from
43
42
private int readOffset ;
@@ -71,10 +70,10 @@ public override long Length
71
70
this . EnsureNotDisposed ( ) ;
72
71
73
72
int length = 0 ;
74
- MemoryChunk chunk = this . memoryChunk ;
73
+ MemoryChunk ? chunk = this . memoryChunk ;
75
74
while ( chunk != null )
76
75
{
77
- MemoryChunk next = chunk . Next ;
76
+ MemoryChunk ? next = chunk . Next ;
78
77
if ( next != null )
79
78
{
80
79
length += chunk . Length ;
@@ -104,8 +103,8 @@ public override long Position
104
103
}
105
104
106
105
int pos = 0 ;
107
- MemoryChunk chunk = this . memoryChunk ;
108
- while ( chunk != this . readChunk )
106
+ MemoryChunk ? chunk = this . memoryChunk ;
107
+ while ( chunk != this . readChunk && chunk is not null )
109
108
{
110
109
pos += chunk . Length ;
111
110
chunk = chunk . Next ;
@@ -126,14 +125,14 @@ public override long Position
126
125
}
127
126
128
127
// Back up current position in case new position is out of range
129
- MemoryChunk backupReadChunk = this . readChunk ;
128
+ MemoryChunk ? backupReadChunk = this . readChunk ;
130
129
int backupReadOffset = this . readOffset ;
131
130
132
131
this . readChunk = null ;
133
132
this . readOffset = 0 ;
134
133
135
134
int leftUntilAtPos = ( int ) value ;
136
- MemoryChunk chunk = this . memoryChunk ;
135
+ MemoryChunk ? chunk = this . memoryChunk ;
137
136
while ( chunk != null )
138
137
{
139
138
if ( ( leftUntilAtPos < chunk . Length )
@@ -365,6 +364,8 @@ private void WriteImpl(ReadOnlySpan<byte> buffer)
365
364
this . writeOffset = 0 ;
366
365
}
367
366
367
+ Guard . NotNull ( this . writeChunk ) ;
368
+
368
369
Span < byte > chunkBuffer = this . writeChunk . Buffer . GetSpan ( ) ;
369
370
int chunkSize = this . writeChunk . Length ;
370
371
int count = buffer . Length ;
@@ -402,6 +403,8 @@ public override void WriteByte(byte value)
402
403
this . writeOffset = 0 ;
403
404
}
404
405
406
+ Guard . NotNull ( this . writeChunk ) ;
407
+
405
408
IMemoryOwner < byte > chunkBuffer = this . writeChunk . Buffer ;
406
409
int chunkSize = this . writeChunk . Length ;
407
410
@@ -426,7 +429,7 @@ public byte[] ToArray()
426
429
int length = ( int ) this . Length ; // This will throw if stream is closed
427
430
byte [ ] copy = new byte [ this . Length ] ;
428
431
429
- MemoryChunk backupReadChunk = this . readChunk ;
432
+ MemoryChunk ? backupReadChunk = this . readChunk ;
430
433
int backupReadOffset = this . readOffset ;
431
434
432
435
this . readChunk = this . memoryChunk ;
@@ -522,15 +525,14 @@ private MemoryChunk AllocateMemoryChunk()
522
525
// available contiguous buffer size.
523
526
IMemoryOwner < byte > buffer = this . allocator . Allocate < byte > ( Math . Min ( this . allocatorCapacity , GetChunkSize ( this . chunkCount ++ ) ) ) ;
524
527
525
- return new MemoryChunk
528
+ return new MemoryChunk ( buffer )
526
529
{
527
- Buffer = buffer ,
528
530
Next = null ,
529
531
Length = buffer . Length ( )
530
532
} ;
531
533
}
532
534
533
- private static void ReleaseMemoryChunks ( MemoryChunk chunk )
535
+ private static void ReleaseMemoryChunks ( MemoryChunk ? chunk )
534
536
{
535
537
while ( chunk != null )
536
538
{
@@ -555,11 +557,13 @@ private sealed class MemoryChunk : IDisposable
555
557
{
556
558
private bool isDisposed ;
557
559
558
- public IMemoryOwner < byte > Buffer { get ; set ; }
560
+ public MemoryChunk ( IMemoryOwner < byte > buffer ) => this . Buffer = buffer ;
561
+
562
+ public IMemoryOwner < byte > Buffer { get ; }
559
563
560
- public MemoryChunk Next { get ; set ; }
564
+ public MemoryChunk ? Next { get ; set ; }
561
565
562
- public int Length { get ; set ; }
566
+ public int Length { get ; init ; }
563
567
564
568
private void Dispose ( bool disposing )
565
569
{
@@ -570,7 +574,6 @@ private void Dispose(bool disposing)
570
574
this . Buffer . Dispose ( ) ;
571
575
}
572
576
573
- this . Buffer = null ;
574
577
this . isDisposed = true ;
575
578
}
576
579
}
0 commit comments