Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Span in Convert.TryFromBase64String()?

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.

like image 453
Morasiu Avatar asked Jul 12 '18 08:07

Morasiu


2 Answers

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.

like image 148
xanatos Avatar answered Nov 18 '22 10:11

xanatos


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));
}
like image 6
Loul G. Avatar answered Nov 18 '22 10:11

Loul G.