-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use RecyclableMemoryStream #16949
Merged
Merged
Use RecyclableMemoryStream #16949
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
a1b7fa9
Use RecyclableMemoryStream
MikeAlhayek b0ad6e6
Remove extra overloads and property dispose
MikeAlhayek 8135846
Merge branch 'main' into ma/RecyclableMemoryStream
MikeAlhayek bb98357
using buffer
MikeAlhayek 1f8db5f
Merge branch 'ma/RecyclableMemoryStream' of https://github.com/Orchar…
MikeAlhayek 72eb01c
use the buffer
MikeAlhayek dba974f
remove unwanted stream
MikeAlhayek 9965bcf
use RecyclableMemoryStream
MikeAlhayek 1978dcd
fix warning
MikeAlhayek 511317a
save
MikeAlhayek fefc90d
Merge branch 'main' into ma/RecyclableMemoryStream
MikeAlhayek 3edaeaf
improvements
MikeAlhayek 4c00119
use helper
MikeAlhayek 7d8d313
fix build
MikeAlhayek a2e834c
remove project references
MikeAlhayek 12b7946
more
MikeAlhayek ab6e124
address feedback
MikeAlhayek 9572007
Fix build
MikeAlhayek 1c98afe
Merge branch 'main' into ma/RecyclableMemoryStream
MikeAlhayek 4716aef
Improve stream usages
sebastienros a6465cb
Use async copy
sebastienros b9cb6a1
Fix tests
sebastienros 20ff540
Revert breaking changes
sebastienros File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System.Text; | ||
|
||
namespace OrchardCore; | ||
|
||
public static class Base64 | ||
{ | ||
/// <summary> | ||
/// Converts a base64 encoded UTF8 string to the original value. | ||
/// </summary> | ||
/// <param name="base64">The base64 encoded string.</param> | ||
/// <returns>The decoded string.</returns> | ||
/// <remarks>This method is equivalent to <c>Encoding.UTF8.GetString(Convert.FromBase64String(base64))</c> but uses a buffer pool to decode the string.</remarks> | ||
public static string FromUTF8Base64String(string base64) | ||
{ | ||
ArgumentNullException.ThrowIfNull(base64); | ||
|
||
// Due to padding the deserialized buffer could be smaller than this value. | ||
var maxBufferLength = GetDeserializedBase64Length(base64.Length); | ||
|
||
using var memoryStream = MemoryStreamFactory.GetStream(maxBufferLength); | ||
var span = memoryStream.GetSpan(maxBufferLength); | ||
|
||
if (!Convert.TryFromBase64String(base64, span, out var bytesWritten)) | ||
{ | ||
throw new FormatException("Invalid Base64 string."); | ||
} | ||
|
||
return Encoding.UTF8.GetString(span.Slice(0, bytesWritten)); | ||
} | ||
|
||
/// <summary> | ||
/// Converts a base64 encoded string to a stream. | ||
/// </summary> | ||
/// <param name="base64">The base64 encoded string.</param> | ||
/// <remarks>The resulting <see cref="Stream"/> should be disposed once used.</remarks> | ||
/// <returns>The decoded stream.</returns> | ||
/// <exception cref="FormatException"></exception> | ||
public static Stream DecodedToStream(string base64) | ||
{ | ||
ArgumentNullException.ThrowIfNull(base64); | ||
|
||
// Due to padding the deserialized buffer could be smaller than this value. | ||
var maxBufferLength = GetDeserializedBase64Length(base64.Length); | ||
|
||
var memoryStream = MemoryStreamFactory.GetStream(maxBufferLength); | ||
var span = memoryStream.GetSpan(maxBufferLength); | ||
|
||
if (!Convert.TryFromBase64String(base64, span, out var bytesWritten)) | ||
{ | ||
throw new FormatException("Invalid Base64 string."); | ||
} | ||
|
||
memoryStream.Advance(bytesWritten); | ||
|
||
return memoryStream; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the maximum buffer length required to decode a base64 string. | ||
/// </summary> | ||
/// <param name="base64Length">The length value to decode.</param> | ||
/// <returns>The size of the decoded buffer.</returns> | ||
public static int GetDeserializedBase64Length(int base64Length) | ||
{ | ||
// Do the multiplication first to prevent precision loss. | ||
return base64Length * 3 / 4; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/OrchardCore/OrchardCore.Abstractions/MemoryStreamFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using Microsoft.IO; | ||
|
||
namespace OrchardCore; | ||
|
||
public static class MemoryStreamFactory | ||
{ | ||
private static readonly RecyclableMemoryStreamManager _manager = new(); | ||
|
||
static MemoryStreamFactory() | ||
{ | ||
var options = new RecyclableMemoryStreamManager.Options | ||
{ | ||
BlockSize = 4 * 1024, // 4 KB | ||
AggressiveBufferReturn = true | ||
}; | ||
|
||
_manager = new RecyclableMemoryStreamManager(options); | ||
} | ||
|
||
public static RecyclableMemoryStream GetStream(string tag = null) | ||
=> _manager.GetStream(tag); | ||
|
||
public static RecyclableMemoryStream GetStream(int requiredSize, string tag = null) | ||
=> _manager.GetStream(tag, requiredSize); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not using the Site Map feature, so I can't say whether this is actually a problem, but this looks wrong. With this change, the stream is disposed as it's being returned for use later (by the File result).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mvarblow it look suspicious to me too. Feel free to test it out, and submit an issue and PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is indeed a problem. I am fixing it.