< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 47
Coverable lines: 47
Total lines: 157
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics.CodeAnalysis;
 5using System.Runtime.InteropServices;
 6
 7namespace System.Globalization
 8{
 9    internal static partial class GlobalizationMode
 10    {
 11        // Split from GlobalizationMode so the whole class can be trimmed when Invariant=true. Trimming tests
 12        // validate this implementation detail.
 13        private static partial class Settings
 14        {
 015            internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Inva
 16#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
 17            internal static bool Hybrid { get; } = true;
 18#endif
 019            internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globa
 20        }
 21
 22        // Note: Invariant=true and Invariant=false are substituted at different levels in the ILLink.Substitutions file
 23        // This allows for the whole Settings nested class to be trimmed when Invariant=true, and allows for the Setting
 24        // static cctor (on Unix) to be preserved when Invariant=false.
 025        internal static bool Invariant => Settings.Invariant;
 26
 27        // same as GlobalizationMode.Invariant but doesn't trigger ICU load in GlobalizationMode.Settings.cctor
 28        // during runtime startup on Browser platform
 29        internal static bool InvariantNoLoad
 30        {
 31            get
 32            {
 33#if TARGET_BROWSER
 34                return AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZ
 35#else
 036                return Settings.Invariant;
 37#endif
 38            }
 39        }
 40
 41#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
 42        internal static bool Hybrid => Settings.Hybrid;
 43#endif
 044        internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly;
 45
 46        private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) =>
 047            TryGetStringValue("System.Globalization.AppLocalIcu", "DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", out value);
 48        private static bool TryGetStringValue(string switchName, string envVariable, [NotNullWhen(true)] out string? val
 49        {
 050            value = AppContext.GetData(switchName) as string;
 051            if (string.IsNullOrEmpty(value))
 52            {
 053                value = Environment.GetEnvironmentVariable(envVariable);
 054                if (string.IsNullOrEmpty(value))
 55                {
 056                    return false;
 57                }
 58            }
 59
 060            return true;
 61        }
 62
 63        private static void LoadAppLocalIcu(string icuSuffixAndVersion)
 64        {
 65            ReadOnlySpan<char> version;
 066            ReadOnlySpan<char> icuSuffix = default;
 67
 68            // Custom built ICU can have a suffix on the name, i.e: libicuucmyapp.so.67.1
 69            // So users would set the runtime switch as: myapp:67.1
 070            int indexOfSeparator = icuSuffixAndVersion.IndexOf(':');
 071            if (indexOfSeparator >= 0)
 72            {
 073                icuSuffix = icuSuffixAndVersion.AsSpan(0, indexOfSeparator);
 074                version = icuSuffixAndVersion.AsSpan(icuSuffix.Length + 1);
 75            }
 76            else
 77            {
 078                version = icuSuffixAndVersion;
 79            }
 80
 081            LoadAppLocalIcuCore(version, icuSuffix);
 082        }
 83
 84        private static string CreateLibraryName(ReadOnlySpan<char> baseName, ReadOnlySpan<char> suffix, ReadOnlySpan<cha
 085            versionAtEnd ?
 086                string.Concat(baseName, suffix, extension, version) :
 087                string.Concat(baseName, suffix, version, extension);
 88
 89        private static IntPtr LoadLibrary(string library, bool failOnLoadFailure)
 90        {
 091            if (!NativeLibrary.TryLoad(library, typeof(object).Assembly, DllImportSearchPath.ApplicationDirectory | DllI
 92            {
 093                Environment.FailFast($"Failed to load app-local ICU: {library}");
 94            }
 95
 096            return lib;
 97        }
 98    }
 99}
 100

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4namespace System.Globalization
 5{
 6    internal static partial class GlobalizationMode
 7    {
 08        internal static bool UseNls { get; } = !Invariant &&
 09            (AppContextConfigHelper.GetBooleanConfig("System.Globalization.UseNls", "DOTNET_SYSTEM_GLOBALIZATION_USENLS"
 010                !LoadIcu());
 11
 12        private static bool LoadIcu()
 13        {
 014            if (!TryGetAppLocalIcuSwitchValue(out string? icuSuffixAndVersion))
 15            {
 016                return Interop.Globalization.LoadICU() != 0;
 17            }
 18
 019            LoadAppLocalIcu(icuSuffixAndVersion);
 020            return true;
 21        }
 22
 23        private static void LoadAppLocalIcuCore(ReadOnlySpan<char> version, ReadOnlySpan<char> suffix)
 24        {
 25            const string extension = ".dll";
 26            const string icuucBase = "icuuc";
 27            const string icuinBase = "icuin";
 028            IntPtr icuucLib = IntPtr.Zero;
 029            IntPtr icuinLib = IntPtr.Zero;
 30
 031            int index = version.IndexOf('.');
 032            if (index > 0)
 33            {
 034                ReadOnlySpan<char> truncatedVersion = version.Slice(0, index);
 035                icuucLib = LoadLibrary(CreateLibraryName(icuucBase, suffix, extension, truncatedVersion), failOnLoadFail
 36
 037                if (icuucLib != IntPtr.Zero)
 38                {
 039                    icuinLib = LoadLibrary(CreateLibraryName(icuinBase, suffix, extension, truncatedVersion), failOnLoad
 40                }
 41            }
 42
 043            if (icuucLib == IntPtr.Zero)
 44            {
 045                icuucLib = LoadLibrary(CreateLibraryName(icuucBase, suffix, extension, version), failOnLoadFailure: true
 46            }
 47
 048            if (icuinLib == IntPtr.Zero)
 49            {
 050                icuinLib = LoadLibrary(CreateLibraryName(icuinBase, suffix, extension, version), failOnLoadFailure: true
 51            }
 52
 053            Interop.Globalization.InitICUFunctions(icuucLib, icuinLib, version, suffix);
 054        }
 55    }
 56}
 57