|
// 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 System.Text;
namespace System.Globalization
{
internal static partial class Normalization
{
internal static bool IsNormalized(ReadOnlySpan<char> source, NormalizationForm normalizationForm = NormalizationForm.FormC)
{
CheckNormalizationForm(normalizationForm);
// In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
// If it's ASCII && one of the 4 main forms, then it's already normalized.
if (GlobalizationMode.Invariant || Ascii.IsValid(source))
{
return true;
}
return GlobalizationMode.UseNls ?
NlsIsNormalized(source, normalizationForm) :
IcuIsNormalized(source, normalizationForm);
}
internal static string Normalize(string strInput, NormalizationForm normalizationForm)
{
CheckNormalizationForm(normalizationForm);
// In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
// If it's ASCII && one of the 4 main forms, then it's already normalized.
if (GlobalizationMode.Invariant || Ascii.IsValid(strInput))
{
return strInput;
}
return GlobalizationMode.UseNls ?
NlsNormalize(strInput, normalizationForm) :
IcuNormalize(strInput, normalizationForm);
}
internal static bool TryNormalize(ReadOnlySpan<char> source, Span<char> destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC)
{
CheckNormalizationForm(normalizationForm);
if (source.Overlaps(destination))
{
ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_SpanOverlappedOperation);
}
// In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
// If it's ASCII && one of the 4 main forms, then it's already normalized.
if (GlobalizationMode.Invariant || Ascii.IsValid(source))
{
if (source.TryCopyTo(destination))
{
charsWritten = source.Length;
return true;
}
charsWritten = 0;
return false;
}
return GlobalizationMode.UseNls ?
NlsTryNormalize(source, destination, out charsWritten, normalizationForm) :
IcuTryNormalize(source, destination, out charsWritten, normalizationForm);
}
internal static int GetNormalizedLength(this ReadOnlySpan<char> source, NormalizationForm normalizationForm = NormalizationForm.FormC)
{
CheckNormalizationForm(normalizationForm);
// In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
// If it's ASCII && one of the 4 main forms, then it's already normalized.
if (GlobalizationMode.Invariant || Ascii.IsValid(source))
{
return source.Length;
}
return GlobalizationMode.UseNls ?
NlsGetNormalizedLength(source, normalizationForm) :
IcuGetNormalizedLength(source, normalizationForm);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CheckNormalizationForm(NormalizationForm normalizationForm)
{
if (normalizationForm != NormalizationForm.FormC &&
normalizationForm != NormalizationForm.FormD &&
normalizationForm != NormalizationForm.FormKC &&
normalizationForm != NormalizationForm.FormKD)
{
throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
}
if ((OperatingSystem.IsBrowser() || OperatingSystem.IsWasi()) &&
!GlobalizationMode.Invariant &&
!GlobalizationMode.UseNls &&
(normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD))
{
// Browser/WASI builds ship without compatibility normalization data.
throw new PlatformNotSupportedException(SR.Argument_UnsupportedNormalizationFormInBrowser);
}
}
}
}
|