From f211ae740ff0cac3bc2894e434365b207039a743 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Sun, 1 Sep 2024 15:03:38 +0200 Subject: [PATCH 1/8] Add FromFile to BinaryData --- .../ref/System.Memory.Data.cs | 4 + .../src/System/BinaryData.cs | 76 +++++++++++++++++++ .../tests/BinaryDataTests.cs | 69 +++++++++++++++++ 3 files changed, 149 insertions(+) diff --git a/src/libraries/System.Memory.Data/ref/System.Memory.Data.cs b/src/libraries/System.Memory.Data/ref/System.Memory.Data.cs index a9730b5c7b3872..f737a1a57b3e30 100644 --- a/src/libraries/System.Memory.Data/ref/System.Memory.Data.cs +++ b/src/libraries/System.Memory.Data/ref/System.Memory.Data.cs @@ -29,6 +29,10 @@ public BinaryData(string data, string? mediaType) { } public static System.BinaryData FromBytes(byte[] data, string? mediaType) { throw null; } public static System.BinaryData FromBytes(System.ReadOnlyMemory data) { throw null; } public static System.BinaryData FromBytes(System.ReadOnlyMemory data, string? mediaType) { throw null; } + public static System.BinaryData FromFile(string path) { throw null; } + public static System.BinaryData FromFile(string path, string? mediaType) { throw null; } + public static System.Threading.Tasks.Task FromFileAsync(string path, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task FromFileAsync(string path, string? mediaType, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed.")] public static System.BinaryData FromObjectAsJson(T jsonSerializable, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } diff --git a/src/libraries/System.Memory.Data/src/System/BinaryData.cs b/src/libraries/System.Memory.Data/src/System/BinaryData.cs index a77a1a5910ea74..37471b542e8d6f 100644 --- a/src/libraries/System.Memory.Data/src/System/BinaryData.cs +++ b/src/libraries/System.Memory.Data/src/System/BinaryData.cs @@ -330,6 +330,82 @@ private static async Task FromStreamAsync(Stream stream, bool async, } } + /// + /// Creates a instance from the specified file. + /// + /// The path to the file. + /// A value representing all of the data from the file. + public static BinaryData FromFile(string path) + { + if (path is null) + { + throw new ArgumentNullException(nameof(path)); + } + + return FromFileAsync(path, async: false).GetAwaiter().GetResult(); + } + + /// + /// Creates a instance from the specified file + /// and sets to value. + /// + /// The path to the file. + /// MIME type of this data, e.g. . + /// A value representing all of the data from the file. + /// + public static BinaryData FromFile(string path, string? mediaType) + { + if (path is null) + { + throw new ArgumentNullException(nameof(path)); + } + + return FromFileAsync(path, async: false, mediaType).GetAwaiter().GetResult(); + } + + /// + /// Creates a instance from the specified file. + /// + /// The path to the file. + /// A token that may be used to cancel the operation. + /// A value representing all of the data from the file. + public static Task FromFileAsync(string path, CancellationToken cancellationToken = default) + { + if (path is null) + { + throw new ArgumentNullException(nameof(path)); + } + + return FromFileAsync(path, async: true, cancellationToken: cancellationToken); + } + + /// + /// Creates a instance from the specified file + /// and sets to value. + /// + /// The path to the file. + /// MIME type of this data, e.g. . + /// A token that may be used to cancel the operation. + /// A value representing all of the data from the file. + /// + public static Task FromFileAsync(string path, string? mediaType, + CancellationToken cancellationToken = default) + { + if (path is null) + { + throw new ArgumentNullException(nameof(path)); + } + + return FromFileAsync(path, async: true, mediaType, cancellationToken); + } + + private static async Task FromFileAsync(string path, bool async, + string? mediaType = default, CancellationToken cancellationToken = default) + { + using FileStream fileStream = File.OpenRead(path); + return await FromStreamAsync(fileStream, async, mediaType, cancellationToken).ConfigureAwait(false); + } + /// /// Creates a instance by serializing the provided object using /// the diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs index fa632a3deedb3e..a63d7cc05ebbce 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs @@ -431,6 +431,59 @@ public void MaxStreamLengthRespected() var data = BinaryData.FromStream(new OverFlowStream(offset: int.MaxValue - 1000)); } + [Fact] + public async Task CanCreateBinaryDataFromFile() + { + byte[] buffer = "some data"u8.ToArray(); + string path = Path.GetTempFileName(); + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path); + Assert.Equal(buffer, data.ToArray()); + + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + data = await BinaryData.FromFileAsync(path); + Assert.Equal(buffer, data.ToArray()); + + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(MediaTypeNames.Application.Soap)] + public async Task CanCreateBinaryDataFromFileWithMediaType(string? mediaType) + { + byte[] buffer = "some data"u8.ToArray(); + string path = Path.GetTempFileName(); + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + data = await BinaryData.FromFileAsync(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + //changing the backing buffer should not affect the BD instance + buffer[3] = (byte)'z'; + Assert.NotEqual(buffer, data.ToMemory().ToArray()); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] public void CanCreateBinaryDataFromCustomType() { @@ -510,6 +563,22 @@ public async Task CreateThrowsOnNullStream() Assert.Contains("stream", ex.Message); } + [Fact] + public async Task CreateFromFileThrowsOnNullPath() + { + var ex = Assert.Throws(() => BinaryData.FromFile(null)); + Assert.Contains("path", ex.Message); + + ex = Assert.Throws(() => BinaryData.FromFile(null, null)); + Assert.Contains("path", ex.Message); + + ex = await Assert.ThrowsAsync(() => BinaryData.FromFileAsync(null)); + Assert.Contains("path", ex.Message); + + ex = await Assert.ThrowsAsync(() => BinaryData.FromFileAsync(null, null)); + Assert.Contains("path", ex.Message); + } + [Fact] public void CreateThrowsOnNullString() { From 510e9f2e419d66f45ede24044d799ec92ccf6eb3 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:16:09 +0200 Subject: [PATCH 2/8] Cleanup temporary files --- .../tests/BinaryDataTests.cs | 82 +++++++++++-------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs index a63d7cc05ebbce..475583fcac2291 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs @@ -352,7 +352,7 @@ public async Task CanCreateBinaryDataFromNonSeekableStream() public async Task CanCreateBinaryDataFromFileStream() { byte[] buffer = "some data"u8.ToArray(); - using FileStream stream = new FileStream(Path.GetTempFileName(), FileMode.Open); + using FileStream stream = new FileStream(Path.GetTempFileName(), FileMode.Open, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose); stream.Write(buffer, 0, buffer.Length); stream.Position = 0; BinaryData data = BinaryData.FromStream(stream); @@ -436,21 +436,28 @@ public async Task CanCreateBinaryDataFromFile() { byte[] buffer = "some data"u8.ToArray(); string path = Path.GetTempFileName(); - File.WriteAllBytes(path, buffer); - BinaryData data = BinaryData.FromFile(path); - Assert.Equal(buffer, data.ToArray()); + try + { + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path); + Assert.Equal(buffer, data.ToArray()); - byte[] output = new byte[buffer.Length]; - var outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); - data = await BinaryData.FromFileAsync(path); - Assert.Equal(buffer, data.ToArray()); + data = await BinaryData.FromFileAsync(path); + Assert.Equal(buffer, data.ToArray()); - outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + } + finally + { + File.Delete(path); + } } [Theory] @@ -461,27 +468,34 @@ public async Task CanCreateBinaryDataFromFileWithMediaType(string? mediaType) { byte[] buffer = "some data"u8.ToArray(); string path = Path.GetTempFileName(); - File.WriteAllBytes(path, buffer); - BinaryData data = BinaryData.FromFile(path, mediaType); - Assert.Equal(buffer, data.ToArray()); - Assert.Equal(mediaType, data.MediaType); - - byte[] output = new byte[buffer.Length]; - var outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - - data = await BinaryData.FromFileAsync(path, mediaType); - Assert.Equal(buffer, data.ToArray()); - Assert.Equal(mediaType, data.MediaType); - - outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - - //changing the backing buffer should not affect the BD instance - buffer[3] = (byte)'z'; - Assert.NotEqual(buffer, data.ToMemory().ToArray()); + try + { + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + data = await BinaryData.FromFileAsync(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + //changing the backing buffer should not affect the BD instance + buffer[3] = (byte)'z'; + Assert.NotEqual(buffer, data.ToMemory().ToArray()); + } + finally + { + File.Delete(path); + } } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] From 38552345f6fb67801964b66e05eac2a636f59998 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:51:54 +0200 Subject: [PATCH 3/8] Use FileStream async mode --- src/libraries/System.Memory.Data/src/System/BinaryData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Memory.Data/src/System/BinaryData.cs b/src/libraries/System.Memory.Data/src/System/BinaryData.cs index 37471b542e8d6f..6c80c57c7ff6b2 100644 --- a/src/libraries/System.Memory.Data/src/System/BinaryData.cs +++ b/src/libraries/System.Memory.Data/src/System/BinaryData.cs @@ -402,7 +402,7 @@ public static Task FromFileAsync(string path, string? mediaType, private static async Task FromFileAsync(string path, bool async, string? mediaType = default, CancellationToken cancellationToken = default) { - using FileStream fileStream = File.OpenRead(path); + using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, async); return await FromStreamAsync(fileStream, async, mediaType, cancellationToken).ConfigureAwait(false); } From f04a48c5aa63a6d64a0603c05ce8655b4f84b0c1 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:19:34 +0100 Subject: [PATCH 4/8] Avoid code duplication --- .../src/System/BinaryData.cs | 38 ++----------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Memory.Data/src/System/BinaryData.cs b/src/libraries/System.Memory.Data/src/System/BinaryData.cs index 6c80c57c7ff6b2..9ed3af1bfd3b12 100644 --- a/src/libraries/System.Memory.Data/src/System/BinaryData.cs +++ b/src/libraries/System.Memory.Data/src/System/BinaryData.cs @@ -225,15 +225,7 @@ public static BinaryData FromString(string data, string? mediaType) /// /// Stream containing the data. /// A value representing all of the data remaining in . - public static BinaryData FromStream(Stream stream) - { - if (stream is null) - { - throw new ArgumentNullException(nameof(stream)); - } - - return FromStreamAsync(stream, async: false).GetAwaiter().GetResult(); - } + public static BinaryData FromStream(Stream stream) => FromStream(stream, mediaType: null); /// /// Creates a instance from the specified stream @@ -262,14 +254,7 @@ public static BinaryData FromStream(Stream stream, string? mediaType) /// A token that may be used to cancel the operation. /// A value representing all of the data remaining in . public static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default) - { - if (stream is null) - { - throw new ArgumentNullException(nameof(stream)); - } - - return FromStreamAsync(stream, async: true, cancellationToken: cancellationToken); - } + => FromStreamAsync(stream, mediaType: null, cancellationToken); /// /// Creates a instance from the specified stream @@ -335,15 +320,7 @@ private static async Task FromStreamAsync(Stream stream, bool async, /// /// The path to the file. /// A value representing all of the data from the file. - public static BinaryData FromFile(string path) - { - if (path is null) - { - throw new ArgumentNullException(nameof(path)); - } - - return FromFileAsync(path, async: false).GetAwaiter().GetResult(); - } + public static BinaryData FromFile(string path) => FromFile(path, mediaType: null); /// /// Creates a instance from the specified file @@ -370,14 +347,7 @@ public static BinaryData FromFile(string path, string? mediaType) /// A token that may be used to cancel the operation. /// A value representing all of the data from the file. public static Task FromFileAsync(string path, CancellationToken cancellationToken = default) - { - if (path is null) - { - throw new ArgumentNullException(nameof(path)); - } - - return FromFileAsync(path, async: true, cancellationToken: cancellationToken); - } + => FromFileAsync(path, mediaType: null, cancellationToken); /// /// Creates a instance from the specified file From 93ed01bb68a14a391f33b3957ecc8c0ac74347e3 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:25:12 +0100 Subject: [PATCH 5/8] Use test helpers --- .../tests/BinaryDataFromFileTests.cs | 67 +++++++++ .../tests/BinaryDataTests.cs | 128 ++---------------- .../tests/System.Memory.Data.Tests.csproj | 3 +- 3 files changed, 81 insertions(+), 117 deletions(-) create mode 100644 src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs new file mode 100644 index 00000000000000..9c85c0f59af4ed --- /dev/null +++ b/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Net.Mime; +using System.Threading.Tasks; +using Xunit; + +namespace System.Tests +{ + public partial class BinaryDataFromFileTests : FileCleanupTestBase + { + [Fact] + public async Task CanCreateBinaryDataFromFile() + { + byte[] buffer = "some data"u8.ToArray(); + string path = GetRandomFilePath(); + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path); + Assert.Equal(buffer, data.ToArray()); + + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + data = await BinaryData.FromFileAsync(path); + Assert.Equal(buffer, data.ToArray()); + + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(MediaTypeNames.Application.Soap)] + public async Task CanCreateBinaryDataFromFileWithMediaType(string? mediaType) + { + byte[] buffer = "some data"u8.ToArray(); + string path = GetRandomFilePath(); + + File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + byte[] output = new byte[buffer.Length]; + var outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + data = await BinaryData.FromFileAsync(path, mediaType); + Assert.Equal(buffer, data.ToArray()); + Assert.Equal(mediaType, data.MediaType); + + outputStream = data.ToStream(); + outputStream.Read(output, 0, (int)outputStream.Length); + Assert.Equal(buffer, output); + + //changing the backing buffer should not affect the BD instance + buffer[3] = (byte)'z'; + Assert.NotEqual(buffer, data.ToMemory().ToArray()); + } + } +} diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs index 475583fcac2291..ba4271dd11af3e 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs @@ -431,73 +431,6 @@ public void MaxStreamLengthRespected() var data = BinaryData.FromStream(new OverFlowStream(offset: int.MaxValue - 1000)); } - [Fact] - public async Task CanCreateBinaryDataFromFile() - { - byte[] buffer = "some data"u8.ToArray(); - string path = Path.GetTempFileName(); - try - { - File.WriteAllBytes(path, buffer); - BinaryData data = BinaryData.FromFile(path); - Assert.Equal(buffer, data.ToArray()); - - byte[] output = new byte[buffer.Length]; - var outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - - data = await BinaryData.FromFileAsync(path); - Assert.Equal(buffer, data.ToArray()); - - outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - } - finally - { - File.Delete(path); - } - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(MediaTypeNames.Application.Soap)] - public async Task CanCreateBinaryDataFromFileWithMediaType(string? mediaType) - { - byte[] buffer = "some data"u8.ToArray(); - string path = Path.GetTempFileName(); - try - { - File.WriteAllBytes(path, buffer); - BinaryData data = BinaryData.FromFile(path, mediaType); - Assert.Equal(buffer, data.ToArray()); - Assert.Equal(mediaType, data.MediaType); - - byte[] output = new byte[buffer.Length]; - var outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - - data = await BinaryData.FromFileAsync(path, mediaType); - Assert.Equal(buffer, data.ToArray()); - Assert.Equal(mediaType, data.MediaType); - - outputStream = data.ToStream(); - outputStream.Read(output, 0, (int)outputStream.Length); - Assert.Equal(buffer, output); - - //changing the backing buffer should not affect the BD instance - buffer[3] = (byte)'z'; - Assert.NotEqual(buffer, data.ToMemory().ToArray()); - } - finally - { - File.Delete(path); - } - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] public void CanCreateBinaryDataFromCustomType() { @@ -564,67 +497,30 @@ public void CanSerializeNullData() [Fact] public async Task CreateThrowsOnNullStream() { - var ex = Assert.Throws(() => BinaryData.FromStream(null)); - Assert.Contains("stream", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromStream(null, null)); - Assert.Contains("stream", ex.Message); - - ex = await Assert.ThrowsAsync(() => BinaryData.FromStreamAsync(null)); - Assert.Contains("stream", ex.Message); - - ex = await Assert.ThrowsAsync(() => BinaryData.FromStreamAsync(null, null)); - Assert.Contains("stream", ex.Message); - } - - [Fact] - public async Task CreateFromFileThrowsOnNullPath() - { - var ex = Assert.Throws(() => BinaryData.FromFile(null)); - Assert.Contains("path", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromFile(null, null)); - Assert.Contains("path", ex.Message); - - ex = await Assert.ThrowsAsync(() => BinaryData.FromFileAsync(null)); - Assert.Contains("path", ex.Message); - - ex = await Assert.ThrowsAsync(() => BinaryData.FromFileAsync(null, null)); - Assert.Contains("path", ex.Message); + AssertExtensions.Throws("stream", () => BinaryData.FromStream(null)); + AssertExtensions.Throws("stream", () => BinaryData.FromStream(null, null)); + await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(null)); + await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(null, null)); } [Fact] public void CreateThrowsOnNullString() { string payload = null; - var ex = Assert.Throws(() => new BinaryData(payload)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => new BinaryData(payload, null)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromString(payload)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromString(payload, null)); - Assert.Contains("data", ex.Message); + var ex = AssertExtensions.Throws("data", () => new BinaryData(payload)); + AssertExtensions.Throws("data", () => new BinaryData(payload, null)); + AssertExtensions.Throws("data", () => BinaryData.FromString(payload)); + AssertExtensions.Throws("data", () => BinaryData.FromString(payload, null)); } [Fact] public void CreateThrowsOnNullArray() { byte[] payload = null; - var ex = Assert.Throws(() => new BinaryData(payload)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => new BinaryData(payload, null)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromBytes(null)); - Assert.Contains("data", ex.Message); - - ex = Assert.Throws(() => BinaryData.FromBytes(null, null)); - Assert.Contains("data", ex.Message); + var ex = AssertExtensions.Throws("data", () => new BinaryData(payload)); + AssertExtensions.Throws("data", () => new BinaryData(payload, null)); + AssertExtensions.Throws("data", () => BinaryData.FromBytes(payload)); + AssertExtensions.Throws("data", () => BinaryData.FromBytes(payload, null)); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] diff --git a/src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj b/src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj index b491d2539a0207..1236c354f983f4 100644 --- a/src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj +++ b/src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj @@ -5,11 +5,12 @@ + - + From fd33c3bd460b4157547acbf4d47552396cd8392c Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Sat, 9 Nov 2024 18:50:58 +0100 Subject: [PATCH 6/8] Use ReadAllBytes{Async} where possible --- .../src/System/BinaryData.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Memory.Data/src/System/BinaryData.cs b/src/libraries/System.Memory.Data/src/System/BinaryData.cs index 9ed3af1bfd3b12..c12afcd09b793e 100644 --- a/src/libraries/System.Memory.Data/src/System/BinaryData.cs +++ b/src/libraries/System.Memory.Data/src/System/BinaryData.cs @@ -243,7 +243,7 @@ public static BinaryData FromStream(Stream stream, string? mediaType) throw new ArgumentNullException(nameof(stream)); } - return FromStreamAsync(stream, async: false, mediaType).GetAwaiter().GetResult(); + return FromStreamAsync(stream, useAsync: false, mediaType).GetAwaiter().GetResult(); } /// @@ -274,10 +274,10 @@ public static Task FromStreamAsync(Stream stream, string? mediaType, throw new ArgumentNullException(nameof(stream)); } - return FromStreamAsync(stream, async: true, mediaType, cancellationToken); + return FromStreamAsync(stream, useAsync: true, mediaType, cancellationToken); } - private static async Task FromStreamAsync(Stream stream, bool async, + private static async Task FromStreamAsync(Stream stream, bool useAsync, string? mediaType = default, CancellationToken cancellationToken = default) { const int CopyToBufferSize = 81920; // the default used by Stream.CopyToAsync @@ -303,7 +303,7 @@ private static async Task FromStreamAsync(Stream stream, bool async, using (memoryStream) { - if (async) + if (useAsync) { await stream.CopyToAsync(memoryStream, bufferSize, cancellationToken).ConfigureAwait(false); } @@ -337,7 +337,7 @@ public static BinaryData FromFile(string path, string? mediaType) throw new ArgumentNullException(nameof(path)); } - return FromFileAsync(path, async: false, mediaType).GetAwaiter().GetResult(); + return new BinaryData(File.ReadAllBytes(path), mediaType); } /// @@ -358,7 +358,7 @@ public static Task FromFileAsync(string path, CancellationToken canc /// A token that may be used to cancel the operation. /// A value representing all of the data from the file. /// - public static Task FromFileAsync(string path, string? mediaType, + public static async Task FromFileAsync(string path, string? mediaType, CancellationToken cancellationToken = default) { if (path is null) @@ -366,14 +366,14 @@ public static Task FromFileAsync(string path, string? mediaType, throw new ArgumentNullException(nameof(path)); } - return FromFileAsync(path, async: true, mediaType, cancellationToken); - } - - private static async Task FromFileAsync(string path, bool async, - string? mediaType = default, CancellationToken cancellationToken = default) - { - using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, async); - return await FromStreamAsync(fileStream, async, mediaType, cancellationToken).ConfigureAwait(false); +#if NET + return new BinaryData( + await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(false), + mediaType); +#else + using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true); + return await FromStreamAsync(fileStream, mediaType, cancellationToken).ConfigureAwait(false); +#endif } /// From 6a30166df4ad5f2530f964437c62e71add717aeb Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Sun, 10 Nov 2024 00:42:58 +0100 Subject: [PATCH 7/8] Async wrapper --- .../System.Memory.Data/src/System/BinaryData.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Memory.Data/src/System/BinaryData.cs b/src/libraries/System.Memory.Data/src/System/BinaryData.cs index c12afcd09b793e..dbe55a353bac83 100644 --- a/src/libraries/System.Memory.Data/src/System/BinaryData.cs +++ b/src/libraries/System.Memory.Data/src/System/BinaryData.cs @@ -358,7 +358,7 @@ public static Task FromFileAsync(string path, CancellationToken canc /// A token that may be used to cancel the operation. /// A value representing all of the data from the file. /// - public static async Task FromFileAsync(string path, string? mediaType, + public static Task FromFileAsync(string path, string? mediaType, CancellationToken cancellationToken = default) { if (path is null) @@ -366,14 +366,19 @@ public static async Task FromFileAsync(string path, string? mediaTyp throw new ArgumentNullException(nameof(path)); } + return Core(); + + async Task Core() + { #if NET - return new BinaryData( - await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(false), - mediaType); + return new BinaryData( + await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(false), + mediaType); #else - using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true); - return await FromStreamAsync(fileStream, mediaType, cancellationToken).ConfigureAwait(false); + using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true); + return await FromStreamAsync(fileStream, mediaType, cancellationToken).ConfigureAwait(false); #endif + } } /// From 50b3f1807fb20d8cb48a9dc9db9dc019c9129a05 Mon Sep 17 00:00:00 2001 From: Emmanuel ANDRE <2341261+manandre@users.noreply.github.com> Date: Sun, 10 Nov 2024 00:45:50 +0100 Subject: [PATCH 8/8] Tests cleaning --- .../tests/BinaryDataFromFileTests.cs | 3 ++- .../System.Memory.Data/tests/BinaryDataTests.cs | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs index 9c85c0f59af4ed..ceb80cc6a4cfd1 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataFromFileTests.cs @@ -16,6 +16,7 @@ public async Task CanCreateBinaryDataFromFile() byte[] buffer = "some data"u8.ToArray(); string path = GetRandomFilePath(); File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path); Assert.Equal(buffer, data.ToArray()); @@ -40,8 +41,8 @@ public async Task CanCreateBinaryDataFromFileWithMediaType(string? mediaType) { byte[] buffer = "some data"u8.ToArray(); string path = GetRandomFilePath(); - File.WriteAllBytes(path, buffer); + BinaryData data = BinaryData.FromFile(path, mediaType); Assert.Equal(buffer, data.ToArray()); Assert.Equal(mediaType, data.MediaType); diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs index ba4271dd11af3e..43310364ff9250 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs @@ -497,17 +497,18 @@ public void CanSerializeNullData() [Fact] public async Task CreateThrowsOnNullStream() { - AssertExtensions.Throws("stream", () => BinaryData.FromStream(null)); - AssertExtensions.Throws("stream", () => BinaryData.FromStream(null, null)); - await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(null)); - await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(null, null)); + Stream stream = null; + AssertExtensions.Throws("stream", () => BinaryData.FromStream(stream)); + AssertExtensions.Throws("stream", () => BinaryData.FromStream(stream, null)); + await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(stream)); + await AssertExtensions.ThrowsAsync("stream", () => BinaryData.FromStreamAsync(stream, null)); } [Fact] public void CreateThrowsOnNullString() { string payload = null; - var ex = AssertExtensions.Throws("data", () => new BinaryData(payload)); + AssertExtensions.Throws("data", () => new BinaryData(payload)); AssertExtensions.Throws("data", () => new BinaryData(payload, null)); AssertExtensions.Throws("data", () => BinaryData.FromString(payload)); AssertExtensions.Throws("data", () => BinaryData.FromString(payload, null)); @@ -517,7 +518,7 @@ public void CreateThrowsOnNullString() public void CreateThrowsOnNullArray() { byte[] payload = null; - var ex = AssertExtensions.Throws("data", () => new BinaryData(payload)); + AssertExtensions.Throws("data", () => new BinaryData(payload)); AssertExtensions.Throws("data", () => new BinaryData(payload, null)); AssertExtensions.Throws("data", () => BinaryData.FromBytes(payload)); AssertExtensions.Throws("data", () => BinaryData.FromBytes(payload, null));