| File: Passkeys\BufferSource.cs | Web Access |
| Project: src\aspnetcore\src\Identity\Core\src\Microsoft.AspNetCore.Identity.csproj (Microsoft.AspNetCore.Identity) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; using System.Text; using System.Text.Json.Serialization; namespace Microsoft.AspNetCore.Identity; /// <summary> /// Represents a base64url-encoded byte buffer for use in passkey operations. /// </summary> /// <remarks> /// This type is named after the JavaScript <c>BufferSource</c> type. /// When included in a JSON payload, it is serialized as a base64url-encoded string. /// When a member of type <c>BufferSource</c> is mentioned in the WebAuthn specification, /// this type can be used to represent it in .NET. /// </remarks> [JsonConverter(typeof(BufferSourceJsonConverter))] internal sealed class BufferSource : IEquatable<BufferSource> { private readonly ReadOnlyMemory<byte> _bytes; /// <summary> /// Gets the length of the byte buffer. /// </summary> public int Length => _bytes.Length; /// <summary> /// Creates a new instance of <see cref="BufferSource"/> from a byte array. /// </summary> public static BufferSource FromBytes(ReadOnlyMemory<byte> bytes) => new(bytes); /// <summary> /// Creates a new instance of <see cref="BufferSource"/> from a string. /// </summary> public static BufferSource FromString(string value) { var buffer = Encoding.UTF8.GetBytes(value); return new(buffer); } private BufferSource(ReadOnlyMemory<byte> buffer) { _bytes = buffer; } /// <summary> /// Gets the byte buffer as a <see cref="ReadOnlyMemory{T}"/>. /// </summary> public ReadOnlyMemory<byte> AsMemory() => _bytes; /// <summary> /// Gets the byte buffer as a <see cref="ReadOnlySpan{T}"/>. /// </summary> public ReadOnlySpan<byte> AsSpan() => _bytes.Span; /// <summary> /// Gets the byte buffer as a byte array. /// </summary> public byte[] ToArray() => _bytes.ToArray(); /// <summary> /// Performs a value-based equality comparison with another <see cref="BufferSource"/> instance. /// </summary> public bool Equals(BufferSource? other) { if (ReferenceEquals(this, other)) { return true; } return other is not null && _bytes.Span.SequenceEqual(other._bytes.Span); } /// <inheritdoc/> public override bool Equals(object? obj) => obj is BufferSource other && Equals(other); /// <inheritdoc/> public override int GetHashCode() => _bytes.GetHashCode(); /// <summary> /// Performs a value-based equality comparison between two <see cref="BufferSource"/> instances. /// </summary> public static bool operator ==(BufferSource? left, BufferSource? right) { if (ReferenceEquals(left, right)) { return true; } if (left is null || right is null) { return false; } return left.Equals(right); } /// <summary> /// Performs a value-based inequality comparison between two <see cref="BufferSource"/> instances. /// </summary> public static bool operator !=(BufferSource? left, BufferSource? right) => !(left == right); /// <summary> /// Gets the UTF-8 string representation of the byte buffer. /// </summary> public override string ToString() { var span = _bytes.Span; if (span.IsEmpty) { return string.Empty; } return Encoding.UTF8.GetString(span); } }