Skip to content

Smdn.Fundamental.Stream version 3.0.2

Compare
Choose a tag to compare
@smdn smdn released this 20 Feb 14:15
· 1963 commits to main since this release
7c76574

Packages

Changes in this release

Change log

API diff

API diff in this release
diff --git a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-net45.apilist.cs b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-net45.apilist.cs
index aee1a694..93449834 100644
--- a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-net45.apilist.cs
+++ b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-net45.apilist.cs
@@ -1,128 +1,129 @@
-// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.1 (net45))
+// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.2)
 //   Name: Smdn.Fundamental.Stream
-//   AssemblyVersion: 3.0.1.0
-//   InformationalVersion: 3.0.1 (net45)
+//   AssemblyVersion: 3.0.2.0
+//   InformationalVersion: 3.0.2+d1a21184e7ae3f93d7ec2857d6ec2ae152e5f517
 //   TargetFramework: .NETFramework,Version=v4.5
 //   Configuration: Release
 
 using System;
 using System.Buffers;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using Smdn.IO.Streams;
 
 namespace Smdn.IO {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public static class StreamExtensions {
     public static void CopyTo(this Stream stream, BinaryWriter writer, int bufferSize = 10240) {}
     public static Task CopyToAsync(this Stream stream, BinaryWriter writer, int bufferSize = 10240, CancellationToken cancellationToken = default) {}
     public static byte[] ReadToEnd(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096) {}
     public static Task<byte[]> ReadToEndAsync(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096, CancellationToken cancellationToken = default) {}
     public static void Write(this Stream stream, ArraySegment<byte> segment) {}
     public static void Write(this Stream stream, ReadOnlySequence<byte> sequence) {}
     public static Task WriteAsync(this Stream stream, ReadOnlySequence<byte> sequence, CancellationToken cancellationToken = default) {}
   }
 }
 
 namespace Smdn.IO.Streams {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public sealed class ChunkedMemoryStream : Stream {
     public delegate ChunkedMemoryStream.Chunk Allocator(int chunkSize);
 
     public abstract class Chunk : IDisposable {
       public byte[] Data;
 
       protected Chunk() {}
 
       public abstract void Dispose();
     }
 
     public static readonly int DefaultChunkSize = 40960;
 
     public ChunkedMemoryStream() {}
     public ChunkedMemoryStream(ChunkedMemoryStream.Allocator allocator) {}
     public ChunkedMemoryStream(int chunkSize) {}
     public ChunkedMemoryStream(int chunkSize, ChunkedMemoryStream.Allocator allocator) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public int ChunkSize { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public override void Close() {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public byte[] ToArray() {}
     public override void Write(byte[] buffer, int offset, int count) {}
     public override void WriteByte(byte @value) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class NonClosingStream : Stream {
     public NonClosingStream(Stream innerStream) {}
     public NonClosingStream(Stream innerStream, bool writable) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public override void Close() {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public override void Write(byte[] buffer, int offset, int count) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class PartialStream :
     Stream,
     ICloneable
   {
     public PartialStream(Stream innerStream, long offset) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, long length, bool leaveInnerStreamOpen) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public bool LeaveInnerStreamOpen { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public PartialStream Clone() {}
     public override void Close() {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length, bool seekToBegin) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length, bool seekToBegin) {}
     public override void Flush() {}
     protected long GetRemainderLength() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     object ICloneable.Clone() {}
     public override void Write(byte[] buffer, int offset, int count) {}
+    public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default) {}
   }
 }
 
diff --git a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard1.6.apilist.cs b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard1.6.apilist.cs
index e1292134..db8161dd 100644
--- a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard1.6.apilist.cs
+++ b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard1.6.apilist.cs
@@ -1,125 +1,126 @@
-// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.1 (netstandard1.6))
+// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.2)
 //   Name: Smdn.Fundamental.Stream
-//   AssemblyVersion: 3.0.1.0
-//   InformationalVersion: 3.0.1 (netstandard1.6)
+//   AssemblyVersion: 3.0.2.0
+//   InformationalVersion: 3.0.2+d1a21184e7ae3f93d7ec2857d6ec2ae152e5f517
 //   TargetFramework: .NETStandard,Version=v1.6
 //   Configuration: Release
 
 using System;
 using System.Buffers;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using Smdn.IO.Streams;
 
 namespace Smdn.IO {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public static class StreamExtensions {
     public static void Close(this Stream stream) {}
     public static void CopyTo(this Stream stream, BinaryWriter writer, int bufferSize = 10240) {}
     public static Task CopyToAsync(this Stream stream, BinaryWriter writer, int bufferSize = 10240, CancellationToken cancellationToken = default) {}
     public static byte[] ReadToEnd(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096) {}
     public static Task<byte[]> ReadToEndAsync(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096, CancellationToken cancellationToken = default) {}
     public static void Write(this Stream stream, ArraySegment<byte> segment) {}
     public static void Write(this Stream stream, ReadOnlySequence<byte> sequence) {}
     public static Task WriteAsync(this Stream stream, ReadOnlySequence<byte> sequence, CancellationToken cancellationToken = default) {}
   }
 }
 
 namespace Smdn.IO.Streams {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public sealed class ChunkedMemoryStream : Stream {
     public delegate ChunkedMemoryStream.Chunk Allocator(int chunkSize);
 
     public abstract class Chunk : IDisposable {
       public byte[] Data;
 
       protected Chunk() {}
 
       public abstract void Dispose();
     }
 
     public static readonly int DefaultChunkSize = 40960;
 
     public ChunkedMemoryStream() {}
     public ChunkedMemoryStream(ChunkedMemoryStream.Allocator allocator) {}
     public ChunkedMemoryStream(int chunkSize) {}
     public ChunkedMemoryStream(int chunkSize, ChunkedMemoryStream.Allocator allocator) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public int ChunkSize { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     protected override void Dispose(bool disposing) {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public byte[] ToArray() {}
     public override void Write(byte[] buffer, int offset, int count) {}
     public override void WriteByte(byte @value) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class NonClosingStream : Stream {
     public NonClosingStream(Stream innerStream) {}
     public NonClosingStream(Stream innerStream, bool writable) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     protected override void Dispose(bool disposing) {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public override void Write(byte[] buffer, int offset, int count) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class PartialStream : Stream {
     public PartialStream(Stream innerStream, long offset) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, long length, bool leaveInnerStreamOpen) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public bool LeaveInnerStreamOpen { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public PartialStream Clone() {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length, bool seekToBegin) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length, bool seekToBegin) {}
     protected override void Dispose(bool disposing) {}
     public override void Flush() {}
     protected long GetRemainderLength() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public override void Write(byte[] buffer, int offset, int count) {}
+    public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default) {}
   }
 }
 
diff --git a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard2.1.apilist.cs b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard2.1.apilist.cs
index 84c919a5..e1a4a59d 100644
--- a/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard2.1.apilist.cs
+++ b/doc/api-list/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream-netstandard2.1.apilist.cs
@@ -1,128 +1,131 @@
-// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.1 (netstandard2.1))
+// Smdn.Fundamental.Stream.dll (Smdn.Fundamental.Stream-3.0.2)
 //   Name: Smdn.Fundamental.Stream
-//   AssemblyVersion: 3.0.1.0
-//   InformationalVersion: 3.0.1 (netstandard2.1)
+//   AssemblyVersion: 3.0.2.0
+//   InformationalVersion: 3.0.2+d1a21184e7ae3f93d7ec2857d6ec2ae152e5f517
 //   TargetFramework: .NETStandard,Version=v2.1
 //   Configuration: Release
 
 using System;
 using System.Buffers;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using Smdn.IO.Streams;
 
 namespace Smdn.IO {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public static class StreamExtensions {
     public static void CopyTo(this Stream stream, BinaryWriter writer, int bufferSize = 10240) {}
     public static Task CopyToAsync(this Stream stream, BinaryWriter writer, int bufferSize = 10240, CancellationToken cancellationToken = default) {}
     public static byte[] ReadToEnd(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096) {}
     public static Task<byte[]> ReadToEndAsync(this Stream stream, int readBufferSize = 4096, int initialCapacity = 4096, CancellationToken cancellationToken = default) {}
     public static void Write(this Stream stream, ArraySegment<byte> segment) {}
     public static void Write(this Stream stream, ReadOnlySequence<byte> sequence) {}
     public static Task WriteAsync(this Stream stream, ReadOnlySequence<byte> sequence, CancellationToken cancellationToken = default) {}
   }
 }
 
 namespace Smdn.IO.Streams {
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public sealed class ChunkedMemoryStream : Stream {
     public delegate ChunkedMemoryStream.Chunk Allocator(int chunkSize);
 
     public abstract class Chunk : IDisposable {
       public byte[] Data;
 
       protected Chunk() {}
 
       public abstract void Dispose();
     }
 
     public static readonly int DefaultChunkSize = 40960;
 
     public ChunkedMemoryStream() {}
     public ChunkedMemoryStream(ChunkedMemoryStream.Allocator allocator) {}
     public ChunkedMemoryStream(int chunkSize) {}
     public ChunkedMemoryStream(int chunkSize, ChunkedMemoryStream.Allocator allocator) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public int ChunkSize { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public override void Close() {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public byte[] ToArray() {}
     public override void Write(byte[] buffer, int offset, int count) {}
     public override void WriteByte(byte @value) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class NonClosingStream : Stream {
     public NonClosingStream(Stream innerStream) {}
     public NonClosingStream(Stream innerStream, bool writable) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public override void Close() {}
     public override void Flush() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     public override void Write(byte[] buffer, int offset, int count) {}
   }
 
   [TypeForwardedFrom("Smdn, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null")]
   public class PartialStream :
     Stream,
     ICloneable
   {
     public PartialStream(Stream innerStream, long offset) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen) {}
     public PartialStream(Stream innerStream, long offset, long length, bool @readonly, bool leaveInnerStreamOpen, bool seekToBegin) {}
     public PartialStream(Stream innerStream, long offset, long length, bool leaveInnerStreamOpen) {}
 
     public override bool CanRead { get; }
     public override bool CanSeek { get; }
     public override bool CanTimeout { get; }
     public override bool CanWrite { get; }
     public Stream InnerStream { get; }
     public bool LeaveInnerStreamOpen { get; }
     public override long Length { get; }
     public override long Position { get; set; }
 
     public PartialStream Clone() {}
     public override void Close() {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long length, bool seekToBegin) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length) {}
     public static PartialStream CreateNonNested(Stream innerOrPartialStream, long offset, long length, bool seekToBegin) {}
     public override void Flush() {}
     protected long GetRemainderLength() {}
     public override int Read(byte[] buffer, int offset, int count) {}
     public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {}
+    public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) {}
     public override int ReadByte() {}
     public override long Seek(long offset, SeekOrigin origin) {}
     public override void SetLength(long @value) {}
     object ICloneable.Clone() {}
     public override void Write(byte[] buffer, int offset, int count) {}
+    public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default) {}
+    public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) {}
   }
 }
 

Changes

Compare changes

Changes in this release
diff --git a/src/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream.csproj b/src/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream.csproj
index 0ecd5141..c47dcc23 100644
--- a/src/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream.csproj
+++ b/src/Smdn.Fundamental.Stream/Smdn.Fundamental.Stream.csproj
@@ -5,16 +5,17 @@ SPDX-License-Identifier: MIT
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>net45;netstandard2.1;netstandard1.6</TargetFrameworks>
-    <VersionPrefix>3.0.1</VersionPrefix>
+    <VersionPrefix>3.0.2</VersionPrefix>
     <VersionSuffix></VersionSuffix>
     <PackageValidationBaselineVersion>3.0.0</PackageValidationBaselineVersion>
   </PropertyGroup>
 
-  <PropertyGroup Label="metadata">
+  <PropertyGroup Label="assembly attributes">
     <CopyrightYear>2021</CopyrightYear>
+  </PropertyGroup>
 
-    <!-- NuGet -->
-    <!--<PackageTags></PackageTags>-->
+  <PropertyGroup Label="package properties">
+    <PackageTags>io;stream;extensions</PackageTags>
   </PropertyGroup>
 
   <ItemGroup>
diff --git a/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/ChunkedMemoryStream.cs b/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/ChunkedMemoryStream.cs
index 4c3f9d84..09e6bd9e 100644
--- a/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/ChunkedMemoryStream.cs
+++ b/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/ChunkedMemoryStream.cs
@@ -14,10 +14,10 @@ public sealed class ChunkedMemoryStream : Stream {
   public abstract class Chunk : IDisposable {
     public abstract void Dispose();
 
-#pragma warning disable SA1401
+#pragma warning disable SA1401, CA1051
     public byte[] Data;
     internal Chunk Next = null;
-#pragma warning restore SA1401
+#pragma warning restore SA1401, CA1051
   }
 
   private class DefaultChunk : Chunk {
diff --git a/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/PartialStream.cs b/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/PartialStream.cs
index dbbbfb01..7f8a386c 100644
--- a/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/PartialStream.cs
+++ b/src/Smdn.Fundamental.Stream/Smdn.IO.Streams/PartialStream.cs
@@ -252,22 +252,61 @@ public class PartialStream :
       return Task.FromResult(0);
   }
 
+#if SYSTEM_IO_STREAM_READASYNC_MEMORY_OF_BYTE
+  public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
+  {
+    CheckDisposed();
+
+    var remainder = GetRemainderLength();
+
+    if (0L < remainder)
+      return stream.ReadAsync(buffer.Slice(0, (int)Math.Min(buffer.Length, remainder)), cancellationToken); // XXX: long -> int
+
+    return new(0);
+  }
+#endif
+
+  private void CheckWriteRemainder(int count, string nameOfCountParameter)
+  {
+    if (count < 0)
+      throw ExceptionUtils.CreateArgumentMustBeZeroOrPositive(nameOfCountParameter, count);
+
+    if (GetRemainderLength() - count < 0L)
+      throw new IOException("attempted to write after end of stream");
+  }
+
   public override void Write(byte[] buffer, int offset, int count)
   {
     CheckDisposed();
     CheckWritable();
+    CheckWriteRemainder(count, nameof(count));
 
-    if (count < 0)
-      throw ExceptionUtils.CreateArgumentMustBeZeroOrPositive(nameof(count), count);
+    stream.Write(buffer, offset, count);
+  }
 
-    var remainder = GetRemainderLength() - count;
+  public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
+  {
+    CheckDisposed();
+    CheckWritable();
+    CheckWriteRemainder(count, nameof(count));
 
-    if (remainder < 0L)
-      throw new IOException("attempted to write after end of stream");
-    else
-      stream.Write(buffer, offset, count);
+    return stream.WriteAsync(buffer, offset, count, cancellationToken);
   }
 
+#if SYSTEM_IO_STREAM_WRITEASYNC_READONLYMEMORY_OF_BYTE
+  public override ValueTask WriteAsync(
+    ReadOnlyMemory<byte> buffer,
+    CancellationToken cancellationToken = default
+  )
+  {
+    CheckDisposed();
+    CheckWritable();
+    CheckWriteRemainder(buffer.Length, nameof(buffer));
+
+    return stream.WriteAsync(buffer, cancellationToken);
+  }
+#endif
+
   private void CheckDisposed()
   {
     if (IsClosed)
diff --git a/src/Smdn.Fundamental.Stream/Smdn.IO/StreamExtensions.cs b/src/Smdn.Fundamental.Stream/Smdn.IO/StreamExtensions.cs
index 9ba99a49..68199c18 100644
--- a/src/Smdn.Fundamental.Stream/Smdn.IO/StreamExtensions.cs
+++ b/src/Smdn.Fundamental.Stream/Smdn.IO/StreamExtensions.cs
@@ -68,7 +68,13 @@ public static class StreamExtensions {
       var buffer = new byte[bufferSize]; // TODO: array pool
 
       for (; ; ) {
-        var read = await stream.ReadAsync(buffer, 0, bufferSize, cancellationToken).ConfigureAwait(false);
+        var read =
+#if SYSTEM_IO_STREAM_READASYNC_MEMORY_OF_BYTE
+          await stream.ReadAsync(buffer.AsMemory(0, bufferSize), cancellationToken)
+#else
+          await stream.ReadAsync(buffer, 0, bufferSize, cancellationToken)
+#endif
+          .ConfigureAwait(false);
 
         if (read <= 0)
           break;

What's Changed

  • Release main/Smdn.Fundamental.Stream-3.0.2 by @smdn in #15

Full Changelog: releases/Smdn.Fundamental.Shell-3.0.1...releases/Smdn.Fundamental.Stream-3.0.2