diff --git a/src/Dapr.Client/DaprClientGrpc.cs b/src/Dapr.Client/DaprClientGrpc.cs index 40df4767c..394b313e2 100644 --- a/src/Dapr.Client/DaprClientGrpc.cs +++ b/src/Dapr.Client/DaprClientGrpc.cs @@ -1670,24 +1670,18 @@ public override async Task> EncryptAsync(string vaultResour ReadOnlyMemory plaintextBytes, string keyName, EncryptionOptions encryptionOptions, CancellationToken cancellationToken = default) { - if (MemoryMarshal.TryGetArray(plaintextBytes, out var plaintextSegment) && plaintextSegment.Array != null) - { - var encryptionResult = await EncryptAsync(vaultResourceName, new MemoryStream(plaintextSegment.Array), - keyName, encryptionOptions, - cancellationToken); + using var memoryStream = plaintextBytes.CreateMemoryStream(true); - var bufferedResult = new ArrayBufferWriter(); + var encryptionResult = + await EncryptAsync(vaultResourceName, memoryStream, keyName, encryptionOptions, cancellationToken); - await foreach (var item in encryptionResult.WithCancellation(cancellationToken)) - { - bufferedResult.Write(item.Span); - } - - return bufferedResult.WrittenMemory; + var bufferedResult = new ArrayBufferWriter(); + await foreach (var item in encryptionResult.WithCancellation(cancellationToken)) + { + bufferedResult.Write(item.Span); } - throw new ArgumentException("The input instance doesn't have a valid underlying data store.", - nameof(plaintextBytes)); + return bufferedResult.WrittenMemory; } /// @@ -1895,22 +1889,18 @@ public override async Task> DecryptAsync(string vaultResour ReadOnlyMemory ciphertextBytes, string keyName, DecryptionOptions decryptionOptions, CancellationToken cancellationToken = default) { - if (MemoryMarshal.TryGetArray(ciphertextBytes, out var ciphertextSegment) && ciphertextSegment.Array != null) - { - var decryptionResult = await DecryptAsync(vaultResourceName, new MemoryStream(ciphertextSegment.Array), - keyName, decryptionOptions, cancellationToken); + using var memoryStream = ciphertextBytes.CreateMemoryStream(true); - var bufferedResult = new ArrayBufferWriter(); - await foreach (var item in decryptionResult.WithCancellation(cancellationToken)) - { - bufferedResult.Write(item.Span); - } - - return bufferedResult.WrittenMemory; + var decryptionResult = + await DecryptAsync(vaultResourceName, memoryStream, keyName, decryptionOptions, cancellationToken); + + var bufferedResult = new ArrayBufferWriter(); + await foreach (var item in decryptionResult.WithCancellation(cancellationToken)) + { + bufferedResult.Write(item.Span); } - throw new ArgumentException("The input instance doesn't have a valid underlying data store", - nameof(ciphertextBytes)); + return bufferedResult.WrittenMemory; } /// diff --git a/src/Dapr.Client/Extensions/ReadOnlyMemoryExtensions.cs b/src/Dapr.Client/Extensions/ReadOnlyMemoryExtensions.cs new file mode 100644 index 000000000..928e2c3ff --- /dev/null +++ b/src/Dapr.Client/Extensions/ReadOnlyMemoryExtensions.cs @@ -0,0 +1,36 @@ +// ------------------------------------------------------------------------ +// Copyright 2025 The Dapr Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Dapr.Client; + +internal static class ReadOnlyMemoryExtensions +{ + public static MemoryStream CreateMemoryStream(this ReadOnlyMemory memory, bool isReadOnly) + { + if (memory.IsEmpty) + { + return new MemoryStream(Array.Empty(), !isReadOnly); + } + + if (MemoryMarshal.TryGetArray(memory, out ArraySegment segment)) + { + return new MemoryStream(segment.Array!, segment.Offset, segment.Count, !isReadOnly); + } + + throw new ArgumentException(nameof(memory), "Unable to create MemoryStream from provided memory value"); + } +}