| File: Routing\RouteContext.cs | Web Access |
| Project: src\aspnetcore\src\Components\Components\src\Microsoft.AspNetCore.Components.csproj (Microsoft.AspNetCore.Components) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text; using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.Routing.Tree; using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Routing; internal sealed class RouteContext { public RouteContext(string path) { Path = path.Contains('%') ? GetDecodedPath(path) : path; [SkipLocalsInit] static string GetDecodedPath(string path) { using var uriBuffer = path.Length < 128 ? new UriBuffer(stackalloc byte[path.Length]) : new UriBuffer(path.Length); var utf8Span = uriBuffer.Buffer; if (Encoding.UTF8.TryGetBytes(path.AsSpan(), utf8Span, out var written)) { utf8Span = utf8Span[..written]; var decodedLength = UrlDecoder.DecodeInPlace(utf8Span, isFormEncoding: false); utf8Span = utf8Span[..decodedLength]; path = Encoding.UTF8.GetString(utf8Span); return path; } return path; } } public string Path { get; set; } public RouteValueDictionary RouteValues { get; set; } = new(); public InboundRouteEntry? Entry { get; set; } [DynamicallyAccessedMembers(Component)] public Type? Handler => Entry?.Handler; public IReadOnlyDictionary<string, object?>? Parameters => RouteValues; private readonly ref struct UriBuffer { private readonly byte[]? _pooled; public Span<byte> Buffer { get; } public UriBuffer(int length) { _pooled = ArrayPool<byte>.Shared.Rent(length); Buffer = _pooled.AsSpan(0, length); } public UriBuffer(Span<byte> buffer) => Buffer = buffer; public void Dispose() { if (_pooled != null) { ArrayPool<byte>.Shared.Return(_pooled); } } } }