Smdn.Fundamental.Stream version 3.0.2
smdn
released this
20 Feb 14:15
·
1963 commits
to main
since this release
Packages
Changes in this release
Change log
- 2022-02-20 update assembly version
- 2022-02-05 use Stream.ReadAsync(Memory) if available
- 2022-02-05 override Stream.WriteAsync(byte[], int, int, CancellationToken) and Stream.WriteAsync(ReadOnlyMemory, CancellationToken)
- 2022-02-05 override Stream.ReadAsync(Memory, CancellationToken)
- 2022-02-04 suppress warning CA1051
- 2022-01-02 define PackageTags
- 2022-01-02 refactor assembly attributes and package properties
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
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
Full Changelog: releases/Smdn.Fundamental.Shell-3.0.1...releases/Smdn.Fundamental.Stream-3.0.2