@@ -101,20 +101,32 @@ public override IAsyncResult BeginWrite(byte[] buffer,
101101 object ? state )
102102 => _stream . BeginWrite ( buffer , offset , count , callback , state ) ;
103103
104+ /// <inheritdoc cref="Stream.Close()" />
105+ public override void Close ( )
106+ {
107+ base . Close ( ) ;
108+ _stream . Close ( ) ;
109+ }
110+
104111 /// <inheritdoc cref="Stream.CopyTo(Stream, int)" />
105112#if NETSTANDARD2_0 || NET462
106- public new virtual void CopyTo ( Stream destination , int bufferSize )
107- => _stream . CopyTo ( destination , bufferSize ) ;
113+ public new virtual void CopyTo ( Stream destination , int bufferSize )
108114#else
109115 public override void CopyTo ( Stream destination , int bufferSize )
110- => _stream . CopyTo ( destination , bufferSize ) ;
111116#endif
117+ {
118+ ValidateCopyToArguments ( this , destination , bufferSize ) ;
119+ _stream . CopyTo ( destination , bufferSize ) ;
120+ }
112121
113122 /// <inheritdoc cref="Stream.CopyToAsync(Stream, int, CancellationToken)" />
114123 public override Task CopyToAsync ( Stream destination ,
115124 int bufferSize ,
116125 CancellationToken cancellationToken )
117- => _stream . CopyToAsync ( destination , bufferSize , cancellationToken ) ;
126+ {
127+ ValidateCopyToArguments ( this , destination , bufferSize ) ;
128+ return _stream . CopyToAsync ( destination , bufferSize , cancellationToken ) ;
129+ }
118130
119131 /// <inheritdoc cref="Stream.EndRead(IAsyncResult)" />
120132 public override int EndRead ( IAsyncResult asyncResult )
@@ -141,9 +153,9 @@ public override int Read(byte[] buffer, int offset, int count)
141153 => _stream . Read ( buffer , offset , count ) ;
142154
143155#if FEATURE_SPAN
144- /// <inheritdoc cref="Stream.Read(Span{byte})" />
145- public override int Read ( Span < byte > buffer )
146- => _stream . Read ( buffer ) ;
156+ /// <inheritdoc cref="Stream.Read(Span{byte})" />
157+ public override int Read ( Span < byte > buffer )
158+ => _stream . Read ( buffer ) ;
147159#endif
148160
149161 /// <inheritdoc cref="Stream.ReadAsync(byte[], int, int, CancellationToken)" />
@@ -154,10 +166,10 @@ public override Task<int> ReadAsync(byte[] buffer,
154166 => _stream . ReadAsync ( buffer , offset , count , cancellationToken ) ;
155167
156168#if FEATURE_SPAN
157- /// <inheritdoc cref="Stream.ReadAsync(Memory{byte}, CancellationToken)" />
158- public override ValueTask < int > ReadAsync ( Memory < byte > buffer ,
159- CancellationToken cancellationToken = new ( ) )
160- => _stream . ReadAsync ( buffer , cancellationToken ) ;
169+ /// <inheritdoc cref="Stream.ReadAsync(Memory{byte}, CancellationToken)" />
170+ public override ValueTask < int > ReadAsync ( Memory < byte > buffer ,
171+ CancellationToken cancellationToken = new ( ) )
172+ => _stream . ReadAsync ( buffer , cancellationToken ) ;
161173#endif
162174
163175 /// <inheritdoc cref="Stream.ReadByte()" />
@@ -181,9 +193,9 @@ public override void Write(byte[] buffer, int offset, int count)
181193 => _stream . Write ( buffer , offset , count ) ;
182194
183195#if FEATURE_SPAN
184- /// <inheritdoc cref="Stream.Write(ReadOnlySpan{byte})" />
185- public override void Write ( ReadOnlySpan < byte > buffer )
186- => _stream . Write ( buffer ) ;
196+ /// <inheritdoc cref="Stream.Write(ReadOnlySpan{byte})" />
197+ public override void Write ( ReadOnlySpan < byte > buffer )
198+ => _stream . Write ( buffer ) ;
187199#endif
188200
189201 /// <inheritdoc cref="Stream.WriteAsync(byte[], int, int, CancellationToken)" />
@@ -194,10 +206,10 @@ public override Task WriteAsync(byte[] buffer,
194206 => _stream . WriteAsync ( buffer , offset , count , cancellationToken ) ;
195207
196208#if FEATURE_SPAN
197- /// <inheritdoc cref="Stream.WriteAsync(ReadOnlyMemory{byte}, CancellationToken)" />
198- public override ValueTask WriteAsync ( ReadOnlyMemory < byte > buffer ,
199- CancellationToken cancellationToken = new ( ) )
200- => _stream . WriteAsync ( buffer , cancellationToken ) ;
209+ /// <inheritdoc cref="Stream.WriteAsync(ReadOnlyMemory{byte}, CancellationToken)" />
210+ public override ValueTask WriteAsync ( ReadOnlyMemory < byte > buffer ,
211+ CancellationToken cancellationToken = new ( ) )
212+ => _stream . WriteAsync ( buffer , cancellationToken ) ;
201213#endif
202214
203215 /// <inheritdoc cref="Stream.WriteByte(byte)" />
@@ -211,6 +223,15 @@ protected override void Dispose(bool disposing)
211223 base . Dispose ( disposing ) ;
212224 }
213225
226+ #if FEATURE_ASYNC_FILE
227+ /// <inheritdoc cref="Stream.DisposeAsync()" />
228+ public override async ValueTask DisposeAsync ( )
229+ {
230+ await _stream . DisposeAsync ( ) ;
231+ await base . DisposeAsync ( ) ;
232+ }
233+ #endif
234+
214235 /// <summary>
215236 /// Allows to cast the internal Stream to a FileStream
216237 /// </summary>
@@ -220,5 +241,38 @@ public static explicit operator FileStream(FileSystemStream fsStream)
220241 {
221242 return ( FileStream ) fsStream . _stream ;
222243 }
244+
245+ private static void ValidateCopyToArguments ( Stream source , Stream destination , int bufferSize )
246+ {
247+ if ( destination == null )
248+ {
249+ throw new ArgumentNullException ( nameof ( destination ) , "Destination cannot be null." ) ;
250+ }
251+
252+ if ( bufferSize <= 0 )
253+ {
254+ throw new ArgumentOutOfRangeException ( nameof ( bufferSize ) , "Buffer size must be greater than zero." ) ;
255+ }
256+
257+ if ( ! destination . CanWrite )
258+ {
259+ if ( destination . CanRead )
260+ {
261+ throw new NotSupportedException ( "Stream does not support writing." ) ;
262+ }
263+
264+ throw new ObjectDisposedException ( "Cannot access a closed Stream." ) ;
265+ }
266+
267+ if ( ! source . CanRead )
268+ {
269+ if ( source . CanWrite )
270+ {
271+ throw new NotSupportedException ( "Stream does not support reading." ) ;
272+ }
273+
274+ throw new ObjectDisposedException ( "Cannot access a closed Stream." ) ;
275+ }
276+ }
223277 }
224278}
0 commit comments