|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
using static System.Buffers.Text.Base64Helper;
namespace System.Buffers.Text
{
// AVX2 version based on https://github.com/aklomp/base64/tree/e516d769a2a432c08404f1981e73b431566057be/lib/arch/avx2
// Vector128 version based on https://github.com/aklomp/base64/tree/e516d769a2a432c08404f1981e73b431566057be/lib/arch/ssse3
/// <summary>
/// Convert between binary data and UTF-8 encoded text that is represented in base 64.
/// </summary>
public static partial class Base64
{
/// <summary>
/// Encode the span of binary data into UTF-8 encoded text represented as base64.
/// </summary>
/// <param name="bytes">The input span which contains binary data that needs to be encoded.</param>
/// <param name="utf8">The output span which contains the result of the operation, i.e. the UTF-8 encoded text in base64.</param>
/// <param name="bytesConsumed">The number of input bytes consumed during the operation. This can be used to slice the input for subsequent calls, if necessary.</param>
/// <param name="bytesWritten">The number of bytes written into the output span. This can be used to slice the output for subsequent calls, if necessary.</param>
/// <param name="isFinalBlock"><see langword="true"/> (default) when the input span contains the entire data to encode.
/// Set to <see langword="true"/> when the source buffer contains the entirety of the data to encode.
/// Set to <see langword="false"/> if this method is being called in a loop and if more input data may follow.
/// At the end of the loop, call this (potentially with an empty source buffer) passing <see langword="true"/>.</param>
/// <returns>It returns the <see cref="OperationStatus"/> enum values:
/// - Done - on successful processing of the entire input span
/// - DestinationTooSmall - if there is not enough space in the output span to fit the encoded input
/// - NeedMoreData - only if <paramref name="isFinalBlock"/> is <see langword="false"/>, otherwise the output is padded if the input is not a multiple of 3
/// It does not return InvalidData since that is not possible for base64 encoding.
/// </returns>
public static OperationStatus EncodeToUtf8(ReadOnlySpan<byte> bytes, Span<byte> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) =>
EncodeTo(default(Base64EncoderByte), bytes, utf8, out bytesConsumed, out bytesWritten, isFinalBlock);
/// <summary>
/// Returns the maximum length (in bytes) of the result if you were to encode binary data within a byte span of size "length".
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="length"/> is less than 0 or larger than 1610612733 (since encode inflates the data by 4/3).
/// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetMaxEncodedToUtf8Length(int length)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)length, MaximumEncodeLength);
return ((length + 2) / 3) * 4;
}
/// <summary>
/// Encode the span of binary data (in-place) into UTF-8 encoded text represented as base 64.
/// The encoded text output is larger than the binary data contained in the input (the operation inflates the data).
/// </summary>
/// <param name="buffer">The input span which contains binary data that needs to be encoded.
/// It needs to be large enough to fit the result of the operation.</param>
/// <param name="dataLength">The amount of binary data contained within the buffer that needs to be encoded
/// (and needs to be smaller than the buffer length).</param>
/// <param name="bytesWritten">The number of bytes written into the buffer.</param>
/// <returns>It returns the OperationStatus enum values:
/// - Done - on successful processing of the entire buffer
/// - DestinationTooSmall - if there is not enough space in the buffer beyond dataLength to fit the result of encoding the input
/// It does not return NeedMoreData since this method tramples the data in the buffer and hence can only be called once with all the data in the buffer.
/// It does not return InvalidData since that is not possible for base 64 encoding.
/// </returns>
public static OperationStatus EncodeToUtf8InPlace(Span<byte> buffer, int dataLength, out int bytesWritten) =>
Base64Helper.EncodeToUtf8InPlace(default(Base64EncoderByte), buffer, dataLength, out bytesWritten);
}
}
|