I was trying to write some try catch for Convert.FromBase64String() and I found out that it already has TryFromBase64String() method. But it needs 3 arguments:
public static bool TryFromBase64String(string s, Span<byte> bytes, out int bytesWritten);
So how can I use Span<byte> bytes there?
I only found this in docs, but without proper description. Maybe this is too obvious.
https://learn.microsoft.com/en-us/dotnet/api/system.convert.tryfrombase64string?view=netcore-2.1
Thank to @Damien_The_Unbeliever and THIS article I found out more about Span. So...
Span is used for saving memory and don't call GC so much. It can store arrays or portion of array, but I still can't figure out how to use it in that method.
As written in the linked questions, System.Span<T> is a new C# 7.2 feature (and the Convert.TryFromBase64String is a newer .NET Core feature)
To use System.Span<> you have to install a nuget package:
Install-Package System.Memory
Then to use it:
byte[] buffer = new byte[((b64string.Length * 3) + 3) / 4 -
(b64string.Length > 0 && b64string[b64string.Length - 1] == '=' ?
b64string.Length > 1 && b64string[b64string.Length - 2] == '=' ?
2 : 1 : 0)];
int written;
bool success = Convert.TryFromBase64String(b64string, buffer, out written);
Where b64string is your base-64 string. The over-complicated size for buffer should be the exact length of the buffer based on the length of the b64string.
You could use it like this, making use of all the TryFromBase64String arguments:
public string DecodeUtf8Base64(string input)
{
var bytes = new Span<byte>(new byte[256]); // 256 is arbitrary
if (!Convert.TryFromBase64String(input, bytes, out var bytesWritten))
{
throw new InvalidOperationException("The input is not a valid base64 string");
}
return Encoding.UTF8.GetString(bytes.Slice(0, bytesWritten));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With