+++ /dev/null
-// 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;
-
-internal static partial class Interop
-{
- internal static unsafe partial class JsGlobalization
- {
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern unsafe int IsNormalized(NormalizationForm normalizationForm, in string source, out int exceptionalResult, out object result);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern unsafe int NormalizeString(NormalizationForm normalizationForm, in string source, char* dstBuffer, int dstBufferCapacity, out int exceptionalResult, out object result);
- }
-}
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFrameworks>$(NetCoreAppCurrent)-browser</TargetFrameworks>
- <TestRuntime>true</TestRuntime>
- <HybridGlobalization>true</HybridGlobalization>
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="..\Normalization\NormalizationAll.cs" />
- <Compile Include="..\Normalization\StringNormalizationTests.cs" />
- </ItemGroup>
-
- <ItemGroup>
- <EmbeddedResource Include="..\Normalization\Data\win8.txt">
- <LogicalName>NormalizationDataWin8</LogicalName>
- </EmbeddedResource>
- <EmbeddedResource Include="..\Normalization\Data\win7.txt">
- <LogicalName>NormalizationDataWin7</LogicalName>
- </EmbeddedResource>
- </ItemGroup>
-</Project>
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Nls.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.WebAssembly.cs" Condition="'$(TargetsBrowser)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberFormatInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberStyles.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Ordinal.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\WeakReference.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\WeakReference.T.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ComAwareWeakReference.cs" />
- <Compile Include="$(CommonPath)Interop\Browser\Interop.Normalization.cs" Condition="'$(TargetsBrowser)' == 'true'">
- <Link>Common\Interop\Interop.Normalization.cs</Link>
- </Compile>
<Compile Include="$(CommonPath)Interop\Browser\Interop.CompareInfo.cs" Condition="'$(TargetsBrowser)' == 'true'">
<Link>Common\Interop\Interop.CompareInfo.cs</Link>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnaryPlusOperators.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnsignedNumber.cs" />
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
+++ /dev/null
-// 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;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace System.Globalization
-{
- internal static partial class Normalization
- {
- private static unsafe bool JsIsNormalized(string strInput, NormalizationForm normalizationForm)
- {
- Debug.Assert(!GlobalizationMode.Invariant);
- Debug.Assert(!GlobalizationMode.UseNls);
-
- ValidateArguments(strInput, normalizationForm);
-
- int ret = Interop.JsGlobalization.IsNormalized(normalizationForm, strInput, out int exception, out object ex_result);
- if (exception != 0)
- throw new Exception((string)ex_result);
-
- return ret == 1;
- }
-
- private static unsafe string JsNormalize(string strInput, NormalizationForm normalizationForm)
- {
- Debug.Assert(!GlobalizationMode.Invariant);
- Debug.Assert(!GlobalizationMode.UseNls);
-
- ValidateArguments(strInput, normalizationForm);
-
- char[]? toReturn = null;
- try
- {
- const int StackallocThreshold = 512;
-
- Span<char> buffer = strInput.Length <= StackallocThreshold
- ? stackalloc char[StackallocThreshold]
- : (toReturn = ArrayPool<char>.Shared.Rent(strInput.Length));
-
- for (int attempt = 0; attempt < 2; attempt++)
- {
- int realLen;
- fixed (char* pDest = &MemoryMarshal.GetReference(buffer))
- {
- realLen = Interop.JsGlobalization.NormalizeString(normalizationForm, strInput, pDest, buffer.Length, out int exception, out object ex_result);
- if (exception != 0)
- throw new Exception((string)ex_result);
- }
-
- if (realLen <= buffer.Length)
- {
- ReadOnlySpan<char> result = buffer.Slice(0, realLen);
- return result.SequenceEqual(strInput)
- ? strInput
- : new string(result);
- }
-
- Debug.Assert(realLen > StackallocThreshold);
-
- if (attempt == 0)
- {
- if (toReturn != null)
- {
- // Clear toReturn first to ensure we don't return the same buffer twice
- char[] temp = toReturn;
- toReturn = null;
- ArrayPool<char>.Shared.Return(temp);
- }
-
- buffer = toReturn = ArrayPool<char>.Shared.Rent(realLen);
- }
- }
-
- throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
- }
- finally
- {
- if (toReturn != null)
- {
- ArrayPool<char>.Shared.Return(toReturn);
- }
- }
- }
- }
-}
return GlobalizationMode.UseNls ?
NlsIsNormalized(strInput, normalizationForm) :
-#if TARGET_BROWSER
- GlobalizationMode.Hybrid ?
- JsIsNormalized(strInput, normalizationForm) :
-#endif
IcuIsNormalized(strInput, normalizationForm);
}
return GlobalizationMode.UseNls ?
NlsNormalize(strInput, normalizationForm) :
-#if TARGET_BROWSER
- GlobalizationMode.Hybrid ?
- JsNormalize(strInput, normalizationForm) :
-#endif
IcuNormalize(strInput, normalizationForm);
}
}
public class NormalizeMeasurement : StringMeasurement
{
+ protected new int len = 8 * 1024;
public override string Name => "Normalize";
public override void RunStep() => str.Normalize();
}
public class IsNormalizedMeasurement : StringMeasurement
{
+ protected new int len = 8 * 1024;
public override string Name => "IsNormalized";
public override void RunStep() => str.IsNormalized();
}
}
public class NormalizeMeasurementASCII : ASCIIStringMeasurement
- {
+ {
+ protected new int len = 8 * 1024;
public override string Name => "Normalize ASCII";
public override void RunStep() => str.Normalize();
}
extern mono_bool mono_wasm_starts_with(MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *is_exception, MonoObject** ex_result);
extern mono_bool mono_wasm_ends_with(MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *is_exception, MonoObject** ex_result);
extern int mono_wasm_index_of(MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool fromBeginning, int *is_exception, MonoObject** ex_result);
-extern mono_bool mono_wasm_is_normalized(int32_t normalizationForm, MonoString **src, int *is_exception, MonoObject** ex_result);
-extern int mono_wasm_normalize_string(int32_t normalizationForm, MonoString **src, uint16_t* dst, int32_t dstLength, int *is_exception, MonoObject** ex_result);
void bindings_initialize_internals (void)
{
mono_add_internal_call ("Interop/JsGlobalization::StartsWith", mono_wasm_starts_with);
mono_add_internal_call ("Interop/JsGlobalization::EndsWith", mono_wasm_ends_with);
mono_add_internal_call ("Interop/JsGlobalization::IndexOf", mono_wasm_index_of);
- mono_add_internal_call ("Interop/JsGlobalization::IsNormalized", mono_wasm_is_normalized);
- mono_add_internal_call ("Interop/JsGlobalization::NormalizeString", mono_wasm_normalize_string);
}
"mono_wasm_starts_with",
"mono_wasm_ends_with",
"mono_wasm_index_of",
- "mono_wasm_is_normalized",
- "mono_wasm_normalize_string",
- "mono_wasm_to_Unicode",
- "mono_wasm_to_ASCII",
"icudt68_dat",
];
} from "./net6-legacy/method-calls";
import { mono_wasm_change_case, mono_wasm_change_case_invariant } from "./hybrid-globalization/change-case";
import { mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_starts_with, mono_wasm_index_of } from "./hybrid-globalization/collations";
-import { mono_wasm_is_normalized, mono_wasm_normalize_string } from "./hybrid-globalization/normalization";
// the methods would be visible to EMCC linker
// --- keep in sync with dotnet.cjs.lib.js ---
mono_wasm_starts_with,
mono_wasm_ends_with,
mono_wasm_index_of,
- mono_wasm_is_normalized,
- mono_wasm_normalize_string,
// threading exports, if threading is enabled
...mono_wasm_threads_exports,
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-import { mono_wasm_new_external_root } from "../roots";
-import { monoStringToString, stringToUTF16 } from "../strings";
-import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal";
-import { Int32Ptr } from "../types/emscripten";
-import { wrap_error_root, wrap_no_error_root } from "../invoke-js";
-
-const NORMALIZATION_FORM_MAP = [undefined, "NFC", "NFD", undefined, undefined, "NFKC", "NFKD"];
-const ERROR = -1;
-
-export function mono_wasm_is_normalized(normalizationForm: number, inputStr: MonoStringRef, is_exception: Int32Ptr, ex_address: MonoObjectRef): number {
- const inputRoot = mono_wasm_new_external_root<MonoString>(inputStr),
- exceptionRoot = mono_wasm_new_external_root<MonoObject>(ex_address);
- try {
- const jsString = monoStringToString(inputRoot);
- if (!jsString)
- throw new Error("Invalid string was received.");
-
- const normalization = normalization_to_string(normalizationForm);
- const result = jsString.normalize(normalization);
- wrap_no_error_root(is_exception, exceptionRoot);
- return result === jsString ? 1 : 0;
- }
- catch (ex) {
- wrap_error_root(is_exception, ex, exceptionRoot);
- return ERROR;
- } finally {
- inputRoot.release();
- exceptionRoot.release();
- }
-}
-
-export function mono_wasm_normalize_string(normalizationForm: number, inputStr: MonoStringRef, dstPtr: number, dstLength: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): number {
- const inputRoot = mono_wasm_new_external_root<MonoString>(inputStr),
- exceptionRoot = mono_wasm_new_external_root<MonoObject>(ex_address);
- try {
- const jsString = monoStringToString(inputRoot);
- if (!jsString)
- throw new Error("Invalid string was received.");
-
- const normalization = normalization_to_string(normalizationForm);
- const result = jsString.normalize(normalization);
-
- // increase the dest buffer
- if (result.length > dstLength)
- return result.length;
- stringToUTF16(dstPtr, dstPtr + 2 * dstLength, result);
- return result.length;
- } catch (ex) {
- wrap_error_root(is_exception, ex, exceptionRoot);
- return ERROR;
- } finally {
- inputRoot.release();
- exceptionRoot.release();
- }
-}
-
-const normalization_to_string = (normalizationForm: number): string => NORMALIZATION_FORM_MAP[normalizationForm] ?? "NFC";
-