Пример #1
0
        private const int ICU_ULOC_FULLNAME_CAPACITY           = 157; // max size of locale name

        /// <summary>
        /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
        /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
        /// </summary>
        private bool InitIcuCultureDataCore()
        {
            Debug.Assert(_sRealName != null);
            Debug.Assert(!GlobalizationMode.Invariant);

            const string ICU_COLLATION_KEYWORD = "@collation=";
            string       realNameBuffer        = _sRealName;

            // Basic validation
            if (!IsValidCultureName(realNameBuffer, out var index))
            {
                return(false);
            }

            // Replace _ (alternate sort) with @collation= for ICU
            ReadOnlySpan <char> alternateSortName = default;

            if (index > 0)
            {
                alternateSortName = realNameBuffer.AsSpan(index + 1);
                realNameBuffer    = string.Concat(realNameBuffer.AsSpan(0, index), ICU_COLLATION_KEYWORD, alternateSortName);
            }

            // Get the locale name from ICU
            if (!GetLocaleName(realNameBuffer, out _sWindowsName))
            {
                return(false); // fail
            }

            // Replace the ICU collation keyword with an _
            Debug.Assert(_sWindowsName != null);
            index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
            if (index >= 0)
            {
                // Use original culture name if alternateSortName is not set, which is possible even if the normalized
                // culture name has "@collation=".
                // "zh-TW-u-co-zhuyin" is a good example. The term "u-co-" means the following part will be the sort name
                // and it will be treated in ICU as "zh-TW@collation=zhuyin".
                _sName = alternateSortName.Length == 0 ? realNameBuffer : string.Concat(_sWindowsName.AsSpan(0, index), "_", alternateSortName);
            }
            else
            {
                _sName = _sWindowsName;
            }
            _sRealName = _sName;

            _iLanguage = LCID;
            if (_iLanguage == 0)
            {
                _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
            }
            _bNeutral         = TwoLetterISOCountryName.Length == 0;
            _sSpecificCulture = _bNeutral ? IcuLocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
            // Remove the sort from sName unless custom culture
            if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
            {
                _sName = _sWindowsName.Substring(0, index);
            }
            return(true);
        }
Пример #2
0
        private const int ICU_ULOC_FULLNAME_CAPACITY           = 157; // max size of locale name

        /// <summary>
        /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
        /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
        /// </summary>
        private bool InitIcuCultureDataCore()
        {
            Debug.Assert(_sRealName != null);
            Debug.Assert(!GlobalizationMode.Invariant);

            const string ICU_COLLATION_KEYWORD = "@collation=";
            string       realNameBuffer        = _sRealName;

            // Basic validation
            if (!IsValidCultureName(realNameBuffer, out var index))
            {
                return(false);
            }

            // Replace _ (alternate sort) with @collation= for ICU
            ReadOnlySpan <char> alternateSortName = default;

            if (index > 0)
            {
                alternateSortName = realNameBuffer.AsSpan(index + 1);
                realNameBuffer    = string.Concat(realNameBuffer.AsSpan(0, index), ICU_COLLATION_KEYWORD, alternateSortName);
            }

            // Get the locale name from ICU
            if (!GetLocaleName(realNameBuffer, out _sWindowsName))
            {
                return(false); // fail
            }

            // Replace the ICU collation keyword with an _
            Debug.Assert(_sWindowsName != null);
            index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
            if (index >= 0)
            {
                _sName = string.Concat(_sWindowsName.AsSpan(0, index), "_", alternateSortName);
            }
            else
            {
                _sName = _sWindowsName;
            }
            _sRealName = _sName;

            _iLanguage = LCID;
            if (_iLanguage == 0)
            {
                _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
            }

            _bNeutral = TwoLetterISOCountryName.Length == 0;

            _sSpecificCulture = _bNeutral ? IcuLocaleData.GetSpecificCultureName(_sRealName) : _sRealName;

            // Remove the sort from sName unless custom culture
            if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
            {
                _sName = _sWindowsName.Substring(0, index);
            }
            return(true);
        }
Пример #3
0
        /// <summary>
        /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
        /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
        /// </summary>
        private unsafe bool IcuInitCultureData()
        {
            Debug.Assert(_sRealName != null);

            Debug.Assert(!GlobalizationMode.Invariant);
            Debug.Assert(!GlobalizationMode.UseNls);

            string realNameBuffer = _sRealName;

            // Basic validation
            if (realNameBuffer.Contains('@'))
            {
                return(false); // don't allow ICU variants to come in directly
            }

            // Replace _ (alternate sort) with @collation= for ICU
            ReadOnlySpan <char> alternateSortName = default;
            int index = realNameBuffer.IndexOf('_');

            if (index > 0)
            {
                if (index >= (realNameBuffer.Length - 1) || // must have characters after _
                    realNameBuffer.IndexOf('_', index + 1) >= 0) // only one _ allowed
                {
                    return(false);                               // fail
                }
                alternateSortName = realNameBuffer.AsSpan(index + 1);
                realNameBuffer    = string.Concat(realNameBuffer.AsSpan(0, index), ICU_COLLATION_KEYWORD, alternateSortName);
            }

            // Get the locale name from ICU
            if (!GetLocaleName(realNameBuffer, out _sWindowsName))
            {
                return(false); // fail
            }

            // Replace the ICU collation keyword with an _
            Debug.Assert(_sWindowsName != null);
            index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
            if (index >= 0)
            {
                _sName = string.Concat(_sWindowsName.AsSpan(0, index), "_", alternateSortName);
            }
            else
            {
                _sName = _sWindowsName;
            }
            _sRealName = _sName;

            _iLanguage = LCID;
            if (_iLanguage == 0)
            {
                _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
            }

            _bNeutral = TwoLetterISOCountryName.Length == 0;

            _sSpecificCulture = _bNeutral ? IcuLocaleData.GetSpecificCultureName(_sRealName) : _sRealName;

            // Remove the sort from sName unless custom culture
            if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
            {
                _sName = _sWindowsName.Substring(0, index);
            }
            return(true);
        }