[Common] Fix setting current CultureInfo 61/160461/1 4.0.1-preview1-00025
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 14 Nov 2017 00:30:03 +0000 (09:30 +0900)
committerSemun Lee <semun.lee@samsung.com>
Thu, 16 Nov 2017 08:20:00 +0000 (08:20 +0000)
Change-Id: Ia8436defb1e51cc395e6598263bf9bddedb79ba0
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
(cherry picked from commit a0c0d4a59cdf4effec08a22bf459b6c145f2b0f8)

src/Tizen.Applications.Common/Interop/Interop.Icu.cs [new file with mode: 0644]
src/Tizen.Applications.Common/Interop/Interop.Libraries.cs [changed mode: 0755->0644]
src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs

diff --git a/src/Tizen.Applications.Common/Interop/Interop.Icu.cs b/src/Tizen.Applications.Common/Interop/Interop.Icu.cs
new file mode 100644 (file)
index 0000000..d5771c4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+    internal static partial class Icu
+    {
+        [DllImport(Libraries.Icuuc, EntryPoint = "uloc_canonicalize")]
+        internal static extern Int32 Canonicalize(string localeID, [Out] StringBuilder name, Int32 nameCapacity, out int err);
+
+        [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getLanguage")]
+        internal static extern Int32 GetLanguage(string localeID, [Out] StringBuilder language, Int32 languageCapacity, out int err);
+
+        [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getScript")]
+        internal static extern Int32 GetScript(string localeID, [Out] StringBuilder script, Int32 scriptCapacity, out int err);
+
+        [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getCountry")]
+        internal static extern Int32 GetCountry(string localeID, [Out] StringBuilder country, Int32 countryCapacity, out int err);
+
+        [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getVariant")]
+        internal static extern Int32 GetVariant(string localeID, [Out] StringBuilder variant, Int32 variantCapacity, out int err);
+    }
+}
old mode 100755 (executable)
new mode 100644 (file)
index 8a417c6..227d014
@@ -27,5 +27,6 @@ internal static partial class Interop
         public const string Glib = "libglib-2.0.so.0";
         public const string Libc = "libc.so.6";
         public const string Application = "libcapi-appfw-application.so.0";
+        public const string Icuuc = "libicuuc.so";
     }
 }
index d21efb1..2917cc7 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Globalization;
+using System.Text;
 using Tizen.Applications.CoreBackend;
 
 namespace Tizen.Applications
@@ -239,69 +240,168 @@ namespace Tizen.Applications
 
         private void ChangeCurrentCultureInfo(string locale)
         {
-            string languageCode = string.Empty;
-            string localeCode = string.Empty;
+            ULocale pLocale = new ULocale(locale);
             CultureInfo currentCultureInfo = null;
 
-            if (locale.Contains("."))
+            try
             {
-                locale = locale.Substring(0, locale.IndexOf("."));
+                currentCultureInfo = new CultureInfo(pLocale.Locale.Replace("_", "-"));
             }
+            catch (CultureNotFoundException)
+            {
+                currentCultureInfo = GetFallbackCultureInfo(pLocale);
+            }
+
+            CultureInfo.CurrentCulture = currentCultureInfo;
+        }
+
+        private CultureInfo GetCultureInfo(string locale)
+        {
+            CultureInfo cultureInfo = null;
 
-            if (locale.Contains("_"))
+            try
             {
-                locale = locale.Replace("_", "-");
+                cultureInfo = new CultureInfo(locale);
             }
+            catch (CultureNotFoundException)
+            {
+                return null;
+            }
+
+            return cultureInfo;
+        }
 
-            var dashIndex = locale.IndexOf("-", StringComparison.Ordinal);
-            if (dashIndex > 0)
+        private CultureInfo GetFallbackCultureInfo(ULocale uLocale)
+        {
+            string locale = string.Empty;
+            CultureInfo fallbackCultureInfo = null;
+
+            if (uLocale.Script != null && uLocale.Country != null)
             {
-                var parts = locale.Split('-');
-                languageCode = parts[0];
-                localeCode = parts[1];
+                locale = uLocale.Language + "-" + uLocale.Script + "-" + uLocale.Country;
+                fallbackCultureInfo = GetCultureInfo(locale);
             }
-            else
+
+            if (fallbackCultureInfo == null && uLocale.Script != null)
             {
-                languageCode = locale;
-                localeCode = "";
+                locale = uLocale.Language + "-" + uLocale.Script;
+                fallbackCultureInfo = GetCultureInfo(locale);
             }
 
-            foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
+            if (fallbackCultureInfo == null && uLocale.Country != null)
             {
-                if (ci.TwoLetterISOLanguageName == languageCode)
-                {
-                    if (localeCode == "")
-                    {
-                        if (ci.Name == languageCode)
-                        {
-                            currentCultureInfo = new CultureInfo(ci.Name);
-                            break;
-                        }
-                    }
-                    else
-                    {
-                        if (ci.Name.Contains(localeCode.ToUpper()))
-                        {
-                            currentCultureInfo = new CultureInfo(ci.Name);
-                            break;
-                        }
-                    }
-                }
+                locale = uLocale.Language + "-" + uLocale.Country;
+                fallbackCultureInfo = GetCultureInfo(locale);
             }
 
-            if (currentCultureInfo == null)
+            if (fallbackCultureInfo == null)
             {
                 try
                 {
-                    currentCultureInfo = new CultureInfo(languageCode);
+                    fallbackCultureInfo = new CultureInfo(uLocale.Language);
                 }
                 catch (CultureNotFoundException)
                 {
-                    currentCultureInfo = new CultureInfo("en");
+                    fallbackCultureInfo = new CultureInfo("en");
                 }
             }
 
-            CultureInfo.CurrentCulture = currentCultureInfo;
+            return fallbackCultureInfo;
+        }
+    }
+
+    internal class ULocale
+    {
+        private const int ICU_ULOC_FULLNAME_CAPACITY = 157;
+        private const int ICU_ULOC_LANG_CAPACITY = 12;
+        private const int ICU_ULOC_SCRIPT_CAPACITY = 6;
+        private const int ICU_ULOC_COUNTRY_CAPACITY = 4;
+        private const int ICU_ULOC_VARIANT_CAPACITY = ICU_ULOC_FULLNAME_CAPACITY;
+        private const int ICU_U_ZERO_ERROR = 0;
+
+        internal ULocale(string locale)
+        {
+            Locale = Canonicalize(locale);
+            Language = GetLanguage(Locale);
+            Script = GetScript(Locale);
+            Country = GetCountry(Locale);
+            Variant = GetVariant(Locale);
+        }
+
+        internal string Locale { get; private set; }
+        internal string Language { get; private set; }
+        internal string Script { get; private set; }
+        internal string Country { get; private set; }
+        internal string Variant { get; private set; }
+
+        private string Canonicalize(string localeName)
+        {
+            int err = ICU_U_ZERO_ERROR;
+
+            // Get the locale name from ICU
+            StringBuilder sb = new StringBuilder(ICU_ULOC_FULLNAME_CAPACITY);
+            if (Interop.Icu.Canonicalize(localeName, sb, sb.Capacity, out err) <= 0)
+            {
+                return null;
+            }
+
+            return sb.ToString();
+        }
+
+        private string GetLanguage(string locale)
+        {
+            int err = ICU_U_ZERO_ERROR;
+
+            // Get the language name from ICU
+            StringBuilder sb = new StringBuilder(ICU_ULOC_LANG_CAPACITY);
+            if (Interop.Icu.GetLanguage(locale, sb, sb.Capacity, out err) <= 0)
+            {
+                return null;
+            }
+
+            return sb.ToString();
+        }
+
+        private string GetScript(string locale)
+        {
+            int err = ICU_U_ZERO_ERROR;
+
+            // Get the script name from ICU
+            StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY);
+            if (Interop.Icu.GetScript(locale, sb, sb.Capacity, out err) <= 0)
+            {
+                return null;
+            }
+
+            return sb.ToString();
+        }
+
+        private string GetCountry(string locale)
+        {
+            int err = ICU_U_ZERO_ERROR;
+
+            // Get the country name from ICU
+            StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY);
+            if (Interop.Icu.GetCountry(locale, sb, sb.Capacity, out err) <= 0)
+            {
+                return null;
+            }
+
+            return sb.ToString();
+        }
+
+        private string GetVariant(string locale)
+        {
+            int err = ICU_U_ZERO_ERROR;
+
+            // Get the country name from ICU
+            StringBuilder sb = new StringBuilder(ICU_ULOC_VARIANT_CAPACITY);
+            if (Interop.Icu.GetVariant(locale, sb, sb.Capacity, out err) <= 0)
+            {
+                return null;
+            }
+
+            return sb.ToString();
         }
     }
 }