Private/Runtime/ConvertTo-OpenApiUriEncoded.ps1
|
function ConvertTo-OpenApiUriEncoded { <# .SYNOPSIS Percent-encodes text for a URI (RFC 3986): unreserved characters are kept, and reserved ones too with -AllowReserved. #> [CmdletBinding()] [OutputType([string])] param( [Parameter()] [AllowNull()] [AllowEmptyString()] [string]$Value, [Parameter()] [switch]$AllowReserved ) if ([string]::IsNullOrEmpty($Value)) { return '' } $unreserved = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~' $reserved = ":/?#[]@!$&'()*+,;=" $builder = New-Object System.Text.StringBuilder $utf8 = New-Object System.Text.UTF8Encoding -ArgumentList $false $index = 0 while ($index -lt $Value.Length) { $character = $Value[$index] if ($unreserved.IndexOf($character) -ge 0 -or ($AllowReserved -and $reserved.IndexOf($character) -ge 0)) { [void]$builder.Append($character) $index++ continue } # Surrogate pairs are encoded together as one code point $length = 1 if ([char]::IsHighSurrogate($character) -and ($index + 1) -lt $Value.Length -and [char]::IsLowSurrogate($Value[$index + 1])) { $length = 2 } foreach ($byte in $utf8.GetBytes($Value.Substring($index, $length))) { [void]$builder.Append('%').Append($byte.ToString('X2', [System.Globalization.CultureInfo]::InvariantCulture)) } $index += $length } return $builder.ToString() } |