Lucene.Net.TestFramework.Support.CultureInfoSupport: Refactored .NET Core implementation to use a pool of codecs and load only those supported on the platform into a list. Rather than using a Win32 API, this will work cross-platform and will still test up to ~500 cultures.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/bfc94fb3 Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/bfc94fb3 Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/bfc94fb3 Branch: refs/heads/api-work Commit: bfc94fb318bc7cf3ec8aead7742c8b5007460874 Parents: 5c3392d Author: Shad Storhaug <[email protected]> Authored: Tue Feb 28 09:00:23 2017 +0700 Committer: Shad Storhaug <[email protected]> Committed: Tue Feb 28 09:00:23 2017 +0700 ---------------------------------------------------------------------- .../Support/CultureInfoSupport.cs | 679 +++++++++++++++++-- 1 file changed, 617 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/bfc94fb3/src/Lucene.Net.TestFramework/Support/CultureInfoSupport.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.TestFramework/Support/CultureInfoSupport.cs b/src/Lucene.Net.TestFramework/Support/CultureInfoSupport.cs index 6f80135..586fbfe 100644 --- a/src/Lucene.Net.TestFramework/Support/CultureInfoSupport.cs +++ b/src/Lucene.Net.TestFramework/Support/CultureInfoSupport.cs @@ -1,80 +1,635 @@ using System; -using System.Collections.Concurrent; +using System.Collections.Generic; using System.Globalization; -using System.Runtime.InteropServices; +using System.Linq; namespace Lucene.Net.Support { public static class CultureInfoSupport { - public static CultureInfo[] GetNeutralAndSpecificCultures() - { #if NETSTANDARD - // Because any well-formed culture (xx-XXXX) will succeed in - // Windows 10, even if the system does not support the culture, - // it did not make sense to enumerate through the cultures. We - // workaround this by pinvoking into Win32 API to get the system - // cultures. When these tests are run on a non-Windows OS, the - // Pinvoke will have to import a Linux DLL that supports the - // same functionality. - // See NativeMethods.EnumSystemLocalesEx for more information. - var results = new ConcurrentBag<CultureInfo>(); - - Func<string, uint, IntPtr, bool> addLocaleFunc = (localeName, dwFlags, lParam) => { - var info = new CultureInfo(localeName); - results.Add(info); - return true; - }; - uint flags = (uint)(NativeMethods.Locale.LOCALE_NEUTRALDATA | NativeMethods.Locale.LOCALE_SPECIFICDATA); - var successful = NativeMethods.EnumSystemLocalesEx( - new NativeMethods.EnumLocalesProcEx(addLocaleFunc), - flags, - IntPtr.Zero, - IntPtr.Zero); + #region culturePool + private static string[] specificCulturePool = new string[] + { + "fr-KM", + "fr-LU", + "fr-MA", + "fr-MC", + "fr-MF", + "fr-MG", + "fr-ML", + "fr-MQ", + "fr-MR", + "fr-MU", + "fr-NC", + "fr-NE", + "fr-PF", + "fr-PM", + "fr-RE", + "fr-RW", + "fr-SC", + "fr-SN", + "fr-SY", + "fr-TD", + "fr-TG", + "fr-TN", + "fr-VU", + "fr-WF", + "fr-YT", + "fur-IT", + "fy-NL", + "ga-IE", + "gd-GB", + "gl-ES", + "gn-PY", + "gsw-CH", + "gsw-FR", + "gsw-LI", + "gu-IN", + "guz-KE", + "gv-IM", + "ha-Latn-GH", + "ha-Latn-NE", + "ha-Latn-NG", + "haw-US", + "he-IL", + "hi-IN", + "hr-BA", + "hr-HR", + "hsb-DE", + "hu-HU", + "hy-AM", + "ia-001", + "ia-FR", + "ibb-NG", + "id-ID", + "ig-NG", + "ii-CN", + "is-IS", + "it-CH", + "it-IT", + "it-SM", + "iu-Cans-CA", + "iu-Latn-CA", + "ja-JP", + "jgo-CM", + "jmc-TZ", + "jv-Java-ID", + "jv-Latn-ID", + "ka-GE", + "kab-DZ", + "kam-KE", + "kde-TZ", + "kea-CV", + "khq-ML", + "ki-KE", + "kk-KZ", + "kkj-CM", + "kl-GL", + "kln-KE", + "km-KH", + "kn-IN", + "ko-KP", + "ko-KR", + "kok-IN", + "kr-NG", + "ks-Arab-IN", + "ks-Deva-IN", + "ksb-TZ", + "ksf-CM", + "ksh-DE", + "ku-Arab-IQ", + "ku-Arab-IR", + "kw-GB", + "ky-KG", + "la-001", + "lag-TZ", + "lb-LU", + "lg-UG", + "lkt-US", + "ln-AO", + "ln-CD", + "ln-CF", + "ln-CG", + "lo-LA", + "lrc-IQ", + "lrc-IR", + "lt-LT", + "lu-CD", + "luo-KE", + "luy-KE", + "lv-LV", + "mas-KE", + "mas-TZ", + "mer-KE", + "mfe-MU", + "mg-MG", + "mgh-MZ", + "mgo-CM", + "mi-NZ", + "mk-MK", + "ml-IN", + "mn-MN", + "mn-Mong-CN", + "mn-Mong-MN", + "mni-IN", + "moh-CA", + "mr-IN", + "ms-BN", + "ms-MY", + "ms-SG", + "mt-MT", + "mua-CM", + "my-MM", + "mzn-IR", + "naq-NA", + "nb-NO", + "nb-SJ", + "nd-ZW", + "ne-IN", + "ne-NP", + "nl-AW", + "nl-BE", + "nl-BQ", + "nl-CW", + "nl-NL", + "nl-SR", + "nl-SX", + "nmg-CM", + "nn-NO", + "nnh-CM", + "nqo-GN", + "nr-ZA", + "nso-ZA", + "nus-SS", + "nyn-UG", + "oc-FR", + "om-ET", + "om-KE", + "or-IN", + "os-GE", + "os-RU", + "pa-Arab-PK", + "pa-IN", + "pap-029", + "pl-PL", + "prg-001", + "prs-AF", + "ps-AF", + "pt-AO", + "pt-BR", + "pt-CV", + "pt-GW", + "pt-MO", + "pt-MZ", + "pt-PT", + "pt-ST", + "pt-TL", + "quc-Latn-GT", + "quz-BO", + "quz-EC", + "quz-PE", + "rm-CH", + "rn-BI", + "ro-MD", + "ro-RO", + "rof-TZ", + "ru-BY", + "ru-KG", + "ru-KZ", + "ru-MD", + "ru-RU", + "ru-UA", + "rw-RW", + "rwk-TZ", + "sa-IN", + "sah-RU", + "saq-KE", + "sbp-TZ", + "sd-Arab-PK", + "sd-Deva-IN", + "se-FI", + "se-NO", + "se-SE", + "seh-MZ", + "ses-ML", + "sg-CF", + "shi-Latn-MA", + "shi-Tfng-MA", + "si-LK", + "sk-SK", + "sl-SI", + "sma-NO", + "sma-SE", + "smj-NO", + "smj-SE", + "smn-FI", + "sms-FI", + "sn-Latn-ZW", + "so-DJ", + "so-ET", + "so-KE", + "so-SO", + "sq-AL", + "sq-MK", + "sq-XK", + "sr-Cyrl-BA", + "sr-Cyrl-ME", + "sr-Cyrl-RS", + "sr-Cyrl-XK", + "sr-Latn-BA", + "sr-Latn-ME", + "sr-Latn-RS", + "sr-Latn-XK", + "ss-SZ", + "ss-ZA", + "ssy-ER", + "st-LS", + "st-ZA", + "sv-AX", + "sv-FI", + "sv-SE", + "sw-CD", + "sw-KE", + "sw-TZ", + "sw-UG", + "syr-SY", + "ta-IN", + "ta-LK", + "ta-MY", + "ta-SG", + "te-IN", + "teo-KE", + "teo-UG", + "tg-Cyrl-TJ", + "th-TH", + "ti-ER", + "ti-ET", + "tig-ER", + "tk-TM", + "tn-BW", + "tn-ZA", + "to-TO", + "tr-CY", + "tr-TR", + "ts-ZA", + "tt-RU", + "twq-NE", + "tzm-Arab-MA", + "tzm-Latn-DZ", + "tzm-Latn-MA", + "tzm-Tfng-MA", + "ug-CN", + "uk-UA", + "ur-IN", + "ur-PK", + "uz-Arab-AF", + "uz-Cyrl-UZ", + "uz-Latn-UZ", + "vai-Latn-LR", + "vai-Vaii-LR", + "ve-ZA", + "vi-VN", + "vo-001", + "vun-TZ", + "wae-CH", + "wal-ET", + "wo-SN", + "xh-ZA", + "xog-UG", + "yav-CM", + "yi-001", + "yo-BJ", + "yo-NG", + "zgh-Tfng-MA", + "zh-CN", + "zh-Hans-HK", + "zh-Hans-MO", + "zh-HK", + "zh-MO", + "zh-SG", + "zh-TW", + "zu-ZA" + }; + private static string[] neutralCulturePool = new string[] + { + "aa", + "af", + "agq", + "ak", + "am", + "ar", + "arn", + "as", + "asa", + "ast", + "az", + "az-Cyrl", + "az-Latn", + "ba", + "bas", + "be", + "bem", + "bez", + "bg", + "bin", + "bm", + "bm-Latn", + "bn", + "bo", + "br", + "brx", + "bs", + "bs-Cyrl", + "bs-Latn", + "byn", + "ca", + "ce", + "cgg", + "chr", + "chr-Cher", + "co", + "cs", + "cu", + "cy", + "da", + "dav", + "de", + "dje", + "dsb", + "dua", + "dv", + "dyo", + "dz", + "ebu", + "ee", + "el", + "en", + "eo", + "es", + "et", + "eu", + "ewo", + "fa", + "ff", + "ff-Latn", + "fi", + "fil", + "fo", + "fr", + "fur", + "fy", + "ga", + "gd", + "gl", + "gn", + "gsw", + "gu", + "guz", + "gv", + "ha", + "ha-Latn", + "haw", + "he", + "hi", + "hr", + "hsb", + "hu", + "hy", + "ia", + "ibb", + "id", + "ig", + "ii", + "is", + "it", + "iu", + "iu-Cans", + "iu-Latn", + "ja", + "jgo", + "jmc", + "jv", + "jv-Java", + "jv-Latn", + "ka", + "kab", + "kam", + "kde", + "kea", + "khq", + "ki", + "kk", + "kkj", + "kl", + "kln", + "km", + "kn", + "ko", + "kok", + "kr", + "ks", + "ks-Arab", + "ks-Deva", + "ksb", + "ksf", + "ksh", + "ku", + "ku-Arab", + "kw", + "ky", + "la", + "lag", + "lb", + "lg", + "lkt", + "ln", + "lo", + "lrc", + "lt", + "lu", + "luo", + "luy", + "lv", + "mas", + "mer", + "mfe", + "mg", + "mgh", + "mgo", + "mi", + "mk", + "ml", + "mn", + "mn-Cyrl", + "mn-Mong", + "mni", + "moh", + "mr", + "ms", + "mt", + "mua", + "my", + "mzn", + "naq", + "nb", + "nd", + "ne", + "nl", + "nmg", + "nn", + "nnh", + "no", + "nqo", + "nr", + "nso", + "nus", + "nyn", + "oc", + "om", + "or", + "os", + "pa", + "pa-Arab", + "pap", + "pl", + "prg", + "prs", + "ps", + "pt", + "quc", + "quc-Latn", + "quz", + "rm", + "rn", + "ro", + "rof", + "ru", + "rw", + "rwk", + "sa", + "sah", + "saq", + "sbp", + "sd", + "sd-Arab", + "sd-Deva", + "se", + "seh", + "ses", + "sg", + "shi", + "shi-Latn", + "shi-Tfng", + "si", + "sk", + "sl", + "sma", + "smj", + "smn", + "sms", + "sn", + "sn-Latn", + "so", + "sq", + "sr", + "sr-Cyrl", + "sr-Latn", + "ss", + "ssy", + "st", + "sv", + "sw", + "syr", + "ta", + "te", + "teo", + "tg", + "tg-Cyrl", + "th", + "ti", + "tig", + "tk", + "tn", + "to", + "tr", + "ts", + "tt", + "twq", + "tzm", + "tzm-Arab", + "tzm-Latn", + "tzm-Tfng", + "ug", + "uk", + "ur", + "uz", + "uz-Arab", + "uz-Cyrl", + "uz-Latn", + "vai", + "vai-Latn", + "vai-Vaii", + "ve", + "vi", + "vo", + "vun", + "wae", + "wal", + "wo", + "xh", + "xog", + "yav", + "yi", + "yo", + "zgh", + "zgh-Tfng", + "zh", + "zh-Hans", + "zh-Hant", + "zu", + "zh-CHS", + "zh-CHT" + }; + #endregion culturePool + private static CultureInfo[] supportedSpecificCultures; + private static CultureInfo[] supportedNeutralCultures; - var cultures = successful ? results.ToArray() : new CultureInfo[0]; -#else - var cultures = - CultureInfo.GetCultures(CultureTypes.SpecificCultures | CultureTypes.NeutralCultures); -#endif - return cultures; + static CultureInfoSupport() + { + supportedSpecificCultures = LoadSupportedCultures(specificCulturePool); + supportedNeutralCultures = LoadSupportedCultures(neutralCulturePool); } - } - static class NativeMethods - { - /// <summary> - /// Because of this issue: https://github.com/dotnet/corefx/issues/1669, - /// it does not make sense to enumerate through the cultures. We work - /// around this by calling into Win32 API, EnumSystemLocalesEx to fetch - /// the OS's cultures. - /// This https://msdn.microsoft.com/en-us/library/windows/desktop/dd317829(v=vs.85).aspx - /// </summary> - [DllImport("Kernel32.dll")] - public static extern bool EnumSystemLocalesEx( - EnumLocalesProcEx lpLocaleEnumProcEx, - uint dwFlags, - IntPtr lParam, - IntPtr lpReserved - ); + private static CultureInfo[] LoadSupportedCultures(string[] culturePool) + { + var cultures = new List<CultureInfo>(); - public delegate bool EnumLocalesProcEx( - [MarshalAs(UnmanagedType.LPWStr)] - string lpLocaleString, - uint dwFlags, - IntPtr lParam); + foreach (var culture in specificCulturePool) + { + try + { + cultures.Add(new CultureInfo(culture)); + } + catch (Exception) + { + // ignore + } + } - [Flags] - public enum Locale + return cultures.ToArray(); + } +#endif + + public static CultureInfo[] GetNeutralAndSpecificCultures() { - LOCALE_ALL = 0, // enumerate all named based locales - LOCALE_WINDOWS = 0x00000001, // shipped locales and/or replacements for them - LOCALE_SUPPLEMENTAL = 0x00000002, // supplemental locales only - LOCALE_ALTERNATE_SORTS = 0x00000004, // alternate sort locales - LOCALE_REPLACEMENT = 0x00000008, // locales that replace shipped locales (callback flag only) - LOCALE_NEUTRALDATA = 0x00000010, // Locales that are "neutral" (language only, region data is default) - LOCALE_SPECIFICDATA = 0x00000020, // Locales that contain language and region data +#if NETSTANDARD + return supportedNeutralCultures.Union(supportedSpecificCultures).ToArray(); +#else + return CultureInfo.GetCultures(CultureTypes.SpecificCultures | CultureTypes.NeutralCultures); +#endif + } } }
