コード例 #1
0
        /// <summary>
        /// Gets the valid characters list.
        /// </summary>
        /// <param name="key">The valid characters parameter key.</param>
        /// <param name="ws">The writing system</param>
        /// <returns></returns>
        private string GetValidCharactersList(string key, IWritingSystem ws)
        {
            if (key.StartsWith("ValidCharacters_"))
            {
                // If the key contains a locale ID, then don't use the default vernacular
                // writing system, build one from the locale.
                string identifier = key.Substring(key.IndexOf("_") + 1);
                ws = m_cache.ServiceLocator.WritingSystemManager.Get(LangTagUtils.ToLangTag(identifier));
            }
            else if (key == "AlwaysValidCharacters")
            {
                var bldr = new StringBuilder(13);

                // Add the vernacular digits 0 through 9.
                for (int i = 0; i < 10; i++)
                {
                    bldr.Append(m_scr.ConvertToString(i));
                }

                if (ws.RightToLeftScript)
                {
                    // Add the LTR and RTL marks.
                    bldr.Append('\u202A');
                    bldr.Append('\u202B');
                }

                // Add the line separator.
                bldr.Append('\u2028');
                return(bldr.ToString());
            }

            var validChars = ValidCharacters.Load(ws, LoadException ?? NoErrorReport, m_legacyOverridesFile);

            return(validChars != null ? validChars.SpaceDelimitedList : string.Empty);
        }
コード例 #2
0
 public void ToIcuLocale()
 {
     // language
     Assert.AreEqual("en", LangTagUtils.ToIcuLocale("en"));
     // language, script
     Assert.AreEqual("en_Latn", LangTagUtils.ToIcuLocale("en-Latn"));
     // language, region
     Assert.AreEqual("en_US", LangTagUtils.ToIcuLocale("en-US"));
     // language, script, region, ICU variant
     Assert.AreEqual("en_Latn_US_X_ETIC", LangTagUtils.ToIcuLocale("en-Latn-US-fonipa-x-etic"));
     // language, ICU variant
     Assert.AreEqual("en__X_EMIC", LangTagUtils.ToIcuLocale("en-fonipa-x-emic"));
     // language, region, ICU variant
     Assert.AreEqual("zh_CN_X_PY", LangTagUtils.ToIcuLocale("zh-CN-pinyin"));
     // private use language
     Assert.AreEqual("xkal", LangTagUtils.ToIcuLocale("qaa-x-kal"));
     // private use language, ICU variant
     Assert.AreEqual("xkal__X_ETIC", LangTagUtils.ToIcuLocale("qaa-fonipa-x-kal-etic"));
     // private use language, private use region
     Assert.AreEqual("xkal_XA", LangTagUtils.ToIcuLocale("qaa-QM-x-kal-XA"));
     // private use language, private use script
     Assert.AreEqual("xkal_Fake", LangTagUtils.ToIcuLocale("qaa-Qaaa-x-kal-Fake"));
     // language, private use script
     Assert.AreEqual("en_Fake", LangTagUtils.ToIcuLocale("en-Qaaa-x-Fake"));
     // language, private use script, private use region
     Assert.AreEqual("en_Fake_QD", LangTagUtils.ToIcuLocale("en-Qaaa-QM-x-Fake-QD"));
     // private use language, script
     Assert.AreEqual("xzzz_Latn", LangTagUtils.ToIcuLocale("qaa-Latn-x-zzz"));
 }
コード例 #3
0
        private void ExportLanguages(TextWriter writer)
        {
            string sAnal = AnalWsTag;
            string sVern = m_cache.WritingSystemFactory.GetStrFromWs(m_cache.DefaultVernWs);

            writer.WriteLine("<Languages defaultAnal=\"{0}\" defaultVern=\"{1}\">",
                             sAnal, sVern);
            IWritingSystemManager manager = m_cache.ServiceLocator.GetInstance <IWritingSystemManager>();

            foreach (var wsLocal in manager.LocalWritingSystems)
            {
                string tag = LangTagUtils.ToLangTag(wsLocal.LanguageSubtag,
                                                    wsLocal.ScriptSubtag, wsLocal.RegionSubtag, wsLocal.VariantSubtag);
                ILgWritingSystem lgws = null;
                int ws = m_cache.WritingSystemFactory.GetWsFromStr(tag);
                if (ws <= 0)
                {
                    continue;
                }
                lgws = m_cache.WritingSystemFactory.get_EngineOrNull(ws);
                string code = wsLocal.LanguageSubtag.Code;
                string type = code.Length == 2 ? "ISO-639-1" : "ISO-639-3";
                writer.WriteLine("<WritingSystem id=\"{0}\" language=\"{1}\" type=\"{2}\">",
                                 tag, code, type);
                writer.WriteLine("<Name><Uni>{0}</Uni></Name>",
                                 XmlUtils.MakeSafeXml(wsLocal.LanguageName));
                writer.WriteLine("<Abbreviation><Uni>{0}</Uni></Abbreviation>",
                                 XmlUtils.MakeSafeXml(wsLocal.Abbreviation));
                // We previously wrote out the LCID, but this is obsolete. It would be unreliable to output the WindowsLcid, which only
                // old writing systems will have. If something needs this, we need to output something new in its place. But I'm pretty sure
                // nothing does...Locale is not used in any of the notebook output transforms.
                //writer.WriteLine("<Locale><Integer val=\"{0}\"/></Locale>", ((ILegacyWritingSystemDefinition)wsLocal).WindowsLcid);
                writer.WriteLine("<RightToLeft><Boolean val=\"{0}\"/></RightToLeft>",
                                 wsLocal.RightToLeftScript ? "true" : "false");
                if (ws == m_cache.DefaultAnalWs)
                {
                    m_fRightToLeft = wsLocal.RightToLeftScript;
                }
                writer.WriteLine("<DefaultFont><Uni>{0}</Uni></DefaultFont>",
                                 XmlUtils.MakeSafeXml(wsLocal.DefaultFontName));
                if (!String.IsNullOrEmpty(wsLocal.DefaultFontFeatures))
                {
                    writer.WriteLine("<DefaultFontFeatures><Uni>{0}</Uni></DefaultFontFeatures>",
                                     XmlUtils.MakeSafeXml(wsLocal.DefaultFontFeatures));
                }
                // The following commented out data are probably never needed.
                //if (!String.IsNullOrEmpty(wsLocal.ValidChars))
                //    writer.WriteLine("<ValidChars><Uni>{0}</Uni></ValidChars>",
                //        XmlUtils.MakeSafeXml(wsLocal.ValidChars));
                //writer.WriteLine("<ICULocale><Uni>{0}</Uni></ICULocale>",
                //    XmlUtils.MakeSafeXml(wsLocal.IcuLocale));
                writer.WriteLine("<SortUsing><Uni>{0}</Uni></SortUsing>",
                                 XmlUtils.MakeSafeXml(wsLocal.SortUsing.ToString()));
                writer.WriteLine("<SortRules><Uni>{0}</Uni></SortRules>",
                                 XmlUtils.MakeSafeXml(wsLocal.SortRules));
                writer.WriteLine("</WritingSystem>");
            }
            writer.WriteLine("</Languages>");
        }
コード例 #4
0
        private void ExportLanguages(TextWriter writer)
        {
            string sAnal = AnalWsTag;
            string sVern = m_cache.WritingSystemFactory.GetStrFromWs(m_cache.DefaultVernWs);

            writer.WriteLine("<Languages defaultAnal=\"{0}\" defaultVern=\"{1}\">",
                             sAnal, sVern);
            IWritingSystemManager manager = m_cache.ServiceLocator.GetInstance <IWritingSystemManager>();

            foreach (var wsLocal in manager.LocalWritingSystems)
            {
                string tag = LangTagUtils.ToLangTag(wsLocal.LanguageSubtag,
                                                    wsLocal.ScriptSubtag, wsLocal.RegionSubtag, wsLocal.VariantSubtag);
                ILgWritingSystem lgws = null;
                int ws = m_cache.WritingSystemFactory.GetWsFromStr(tag);
                if (ws <= 0)
                {
                    continue;
                }
                lgws = m_cache.WritingSystemFactory.get_EngineOrNull(ws);
                string code = wsLocal.LanguageSubtag.Code;
                string type = code.Length == 2 ? "ISO-639-1" : "ISO-639-3";
                writer.WriteLine("<WritingSystem id=\"{0}\" language=\"{1}\" type=\"{2}\">",
                                 tag, code, type);
                writer.WriteLine("<Name><Uni>{0}</Uni></Name>",
                                 XmlUtils.MakeSafeXml(wsLocal.LanguageName));
                writer.WriteLine("<Abbreviation><Uni>{0}</Uni></Abbreviation>",
                                 XmlUtils.MakeSafeXml(wsLocal.Abbreviation));
                writer.WriteLine("<Locale><Integer val=\"{0}\"/></Locale>", wsLocal.LCID);
                writer.WriteLine("<RightToLeft><Boolean val=\"{0}\"/></RightToLeft>",
                                 wsLocal.RightToLeftScript ? "true" : "false");
                if (ws == m_cache.DefaultAnalWs)
                {
                    m_fRightToLeft = wsLocal.RightToLeftScript;
                }
                writer.WriteLine("<DefaultFont><Uni>{0}</Uni></DefaultFont>",
                                 XmlUtils.MakeSafeXml(wsLocal.DefaultFontName));
                if (!String.IsNullOrEmpty(wsLocal.DefaultFontFeatures))
                {
                    writer.WriteLine("<DefaultFontFeatures><Uni>{0}</Uni></DefaultFontFeatures>",
                                     XmlUtils.MakeSafeXml(wsLocal.DefaultFontFeatures));
                }
                // The following commented out data are probably never needed.
                //if (!String.IsNullOrEmpty(wsLocal.ValidChars))
                //    writer.WriteLine("<ValidChars><Uni>{0}</Uni></ValidChars>",
                //        XmlUtils.MakeSafeXml(wsLocal.ValidChars));
                //writer.WriteLine("<ICULocale><Uni>{0}</Uni></ICULocale>",
                //    XmlUtils.MakeSafeXml(wsLocal.IcuLocale));
                writer.WriteLine("<SortUsing><Uni>{0}</Uni></SortUsing>",
                                 XmlUtils.MakeSafeXml(wsLocal.SortUsing.ToString()));
                writer.WriteLine("<SortRules><Uni>{0}</Uni></SortRules>",
                                 XmlUtils.MakeSafeXml(wsLocal.SortRules));
                writer.WriteLine("</WritingSystem>");
            }
            writer.WriteLine("</Languages>");
        }
コード例 #5
0
        /// <summary>
        /// Split up the variant into the true (standard) variant(s), returned in variant;
        /// the part the comes (or should come) before the position'th custom item, where
        /// position is 0 for language, 1 for script, 2 for region, 4 for variant, returned as the main output;
        /// and the private use part before the indicated item, in leadIn.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="leadIn"></param>
        /// <param name="variant"></param>
        /// <returns></returns>
        internal string GetPartsOfVariant(int position, out string leadIn, out string variant)
        {
            int index = position;

            if (position > 2 && !Region.Equals("QM", StringComparison.OrdinalIgnoreCase))
            {
                position--;
            }
            if (position > 1 && !Script.Equals("Qaaa", StringComparison.OrdinalIgnoreCase))
            {
                position--;
            }
            if (position > 0 && !(Language.Equals("qaa", StringComparison.OrdinalIgnoreCase)))
            {
                position--;
            }
            string suffix = Variant ?? "";

            // set variant to the non-private-use part of the variant and suffix to the private-use part (without the x).
            variant = "";
            suffix  = LangTagUtils.GetPrivateUseAndStandardVariant(suffix, out variant);
            // Now set leadIn to the parts that correspond to any prior custom things, and suffix to what's left, possibly starting with oldValue
            leadIn = "";
            for (int i = 0; i < position; i++)
            {
                if (leadIn.Length > 0)
                {
                    leadIn += "-";
                }
                int hyphen = suffix.IndexOf("-");
                if (hyphen >= 0)
                {
                    leadIn += suffix.Substring(0, hyphen);
                    suffix  = suffix.Substring(hyphen + 1);
                }
                else if (suffix.Length > 0)
                {
                    leadIn += suffix;
                    suffix  = "";
                }
                // missing expected part to match leading item. Fill in default.
                else if (i == 0)
                {
                    leadIn += "qaa";
                }
                else
                {
                    leadIn += "Qaaa";
                }
            }
            return(suffix);
        }
コード例 #6
0
        /// <summary>
        /// Returns an ISO 639 language tag that is guaranteed to be valid and unique for both the
        /// local and the global writing system store.
        /// NOTE: This method should only be used for writing systems that are custom (i.e. not
        /// defined in the current version of the ethnologue).
        /// The returned code will *not* have the 'x-' prefix denoting a user-defined writing system,
        /// but it will check that an existing user-defined writing system does not exist with
        /// the returned language tag.
        /// This method also does not worry about regions, variants, etc. as it's use is restricted to
        /// the language tag for a custom writing system.
        /// </summary>
        /// <param name="langName">The full name of the language.</param>
        public string GetValidLangTagForNewLang(string langName)
        {
            string        nameD   = langName.Normalize(NormalizationForm.FormD);    // Get the name in NFD format
            StringBuilder builder = new StringBuilder(nameD.ToLowerInvariant());
            int           index   = 0;

            while (index < builder.Length)
            {
                char c         = builder[index];
                bool charValid = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
                if (!charValid)
                {
                    // Found an invalid character, so remove it.
                    builder.Remove(index, 1);
                    continue;
                }
                index++;
            }

            string isoCode = builder.ToString().Substring(0, Math.Min(3, builder.Length));

            if (LangTagUtils.IsLanguageCodeValid(isoCode) && !LangTagInUse("qaa-x-" + isoCode))
            {
                return(isoCode);                // The generated code is valid and not in use by the local or global store
            }
            // We failed to generate a valid, unused language tag from the language name so
            // find one that isn't taken starting with 'aaa' and incrementing ('aab', 'aac', etc.)
            builder.Remove(0, builder.Length);             // Clear the builder
            builder.Append("aaa");
            while (LangTagInUse("qaa-x-" + builder))
            {
                char newCharLast = (char)(builder[2] + 1);
                if (newCharLast > 'z')
                {
                    // Incremented the last letter too far so reset it back to 'a' and increment the middle letter
                    newCharLast = 'a';
                    char newCharMiddle = (char)(builder[1] + 1);
                    if (newCharMiddle > 'z')
                    {
                        // Incremented the middle letter too far so reset it back to 'a' and increment the first letter
                        // Assume we won't ever have more then 4096 (26^3) custom writing systems
                        newCharMiddle = 'a';
                        builder[0]    = (char)(builder[0] + 1);
                    }
                    builder[1] = newCharMiddle;
                }
                builder[2] = newCharLast;
            }
            return(builder.ToString());
        }
コード例 #7
0
        /// <summary>Deal with special Audio handling</summary>
        private void HandleAudioVariant()
        {
            if (VariantSubtag != null && VariantSubtag.Code.Equals(ksAudioVariant, StringComparison.OrdinalIgnoreCase))
            {
                if (m_ws is WritingSystemDefinition)
                {
                    ((WritingSystemDefinition)m_ws).IsVoice = true;
                }
                m_scriptName.Enabled = false;
                var newScriptName = LangTagUtils.GetScriptSubtag(ksAudioScript).Name ?? "Audio";
                if (m_scriptNameString != newScriptName)
                {
                    if (m_scriptName.FindStringExact(newScriptName) < 0)
                    {
                        m_scriptName.Items.Add(LangTagUtils.GetScriptSubtag(ksAudioScript));
                    }

                    ScriptName = newScriptName;
                }
                m_variantAbbrev.Text    = ksAudioVariant.ToLowerInvariant();
                m_variantAbbrev.Enabled = false;
                m_scriptAbbrev.Text     = ksAudioScript;
                // Set after changing script, to avoid intermediate invalid state.
                m_ws.VariantSubtag = VariantSubtag;
            }
            else
            {
                //we are changing from Audio to something else
                if (m_scriptAbbrev.Text == ksAudioScript)
                {
                    m_scriptAbbrev.Text        = "";
                    ScriptName                 = "";
                    m_enableLangTagSideEffects = true;
                }

                if (m_ws is WritingSystemDefinition)
                {
                    ((WritingSystemDefinition)m_ws).IsVoice = false;
                }

                // Safest to set AFTER we turn off IsVoice, but BEFORE we change the script, to avoid
                // a tempoarty invalid state. But we can't, too bad, it's invalid until this line.
                m_ws.VariantSubtag = VariantSubtag;

                m_scriptName.Enabled = true;
            }
        }
コード例 #8
0
        /// -----------------------------------------------------------------------------------
        /// <summary>
        /// Find or create the writing system code for the given RFC4646 language tag. If it's
        /// not in either the list of vernacular writing systems or the list of analysis
        /// writing systems, add it to the list of analysis writing systems.
        /// </summary>
        /// -----------------------------------------------------------------------------------
        public static int GetWsForLocale(string locale)
        {
            string         identifier = LangTagUtils.ToLangTag(locale);
            IWritingSystem ws;

            if (s_scr.Cache.ServiceLocator.WritingSystemManager.TryGetOrSet(identifier, out ws))
            {
                if (!s_scr.Cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems.Contains(ws))
                {
                    s_scr.Cache.ServiceLocator.WritingSystems.AddToCurrentAnalysisWritingSystems(ws);
                }
                return(ws.Handle);
            }

            throw new UnknownPalasoWsException(identifier + " is an unknown RFC5646 language tag.",
                                               locale, identifier);
        }
コード例 #9
0
        /// <summary>
        /// Creates a new writing system.
        /// </summary>
        /// <returns></returns>
        public IWritingSystem Create(string identifier)
        {
            lock (m_syncRoot)
            {
                if (m_globalStore != null)
                {
                    IWritingSystemDefinition globalWs;
                    if (m_globalStore.TryGet(identifier, out globalWs))
                    {
                        return((PalasoWritingSystem)m_globalStore.MakeDuplicate(globalWs));
                    }
                }
            }

            LanguageSubtag languageSubtag;
            ScriptSubtag   scriptSubtag;
            RegionSubtag   regionSubtag;
            VariantSubtag  variantSubtag;

            if (!LangTagUtils.GetSubtags(identifier, out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag))
            {
                throw new ArgumentException(identifier + " is not a valid RFC5646 language tag.");
            }
            var result = Create(languageSubtag, scriptSubtag, regionSubtag, variantSubtag);

            if (TemplateFolder != null)
            {
                // try in our master template file
                // Todo: have property TemplateFolderPath, initialize in FdoBackendProvider.InitializeWritingSystemManager
                var template = Path.Combine(TemplateFolder, Path.ChangeExtension(identifier, "ldml"));
                if (File.Exists(template))
                {
                    var loader = new FwLdmlAdaptor();
                    loader.Read(template, (WritingSystemDefinition)result);
                }
            }
            return(result);
        }
コード例 #10
0
        public void ToLangTag()
        {
            // language
            Assert.AreEqual("en", LangTagUtils.ToLangTag("en"));
            // language, script
            Assert.AreEqual("en-Latn", LangTagUtils.ToLangTag("en_Latn"));
            // language, region
            Assert.AreEqual("en-US", LangTagUtils.ToLangTag("en_US"));
            // language, script, region, ICU variant
            Assert.AreEqual("en-Latn-US-fonipa-x-etic", LangTagUtils.ToLangTag("en_Latn_US_X_ETIC"));
            // language, ICU variant
            Assert.AreEqual("en-fonipa-x-emic", LangTagUtils.ToLangTag("en__X_EMIC"));
            // language, region, ICU variant
            Assert.AreEqual("zh-CN-pinyin", LangTagUtils.ToLangTag("zh_CN_X_PY"));
            // private use language
            Assert.AreEqual("qaa-x-kal", LangTagUtils.ToLangTag("xkal"));
            // private use language, custom ICU variant
            Assert.AreEqual("qaa-fonipa-x-kal", LangTagUtils.ToLangTag("xkal__IPA"));
            // private use language, (standard) private use region
            Assert.AreEqual("qaa-XA-x-kal", LangTagUtils.ToLangTag("xkal_XA"));
            // private use language, (non-standard) private use script
            Assert.AreEqual("qaa-Qaaa-x-kal-Fake", LangTagUtils.ToLangTag("xkal_Fake"));
            // language, private use script
            Assert.AreEqual("en-Qaaa-x-Fake", LangTagUtils.ToLangTag("en_Fake"));
            // language, private use script, private use region
            Assert.AreEqual("en-Qaaa-QM-x-Fake-QD", LangTagUtils.ToLangTag("en_Fake_QD"));
            // private use language, script
            Assert.AreEqual("qaa-Latn-x-zzz", LangTagUtils.ToLangTag("zzz_Latn"));
            // convert older FW language tags
            Assert.AreEqual("slu", LangTagUtils.ToLangTag("eslu"));
            // other possibilities from FW6.0.6
            Assert.AreEqual("qaa-x-bcd", LangTagUtils.ToLangTag("x123"));
            Assert.AreEqual("qaa-x-kac", LangTagUtils.ToLangTag("xka2"));

            // following are already lang tags
            Assert.AreEqual("en-US", LangTagUtils.ToLangTag("en-US"));
            Assert.AreEqual("en-Latn-US-fonipa-x-etic", LangTagUtils.ToLangTag("en-Latn-US-fonipa-x-etic"));
        }
コード例 #11
0
        public bool CheckValid()
        {
            CheckDisposed();

            string caption = FwCoreDlgControls.kstidError;

            ScriptSubtag scriptSubtag = ScriptSubtag;

            // Can't allow a script name without an abbreviation.
            if (scriptSubtag == null && !string.IsNullOrEmpty(m_scriptName.Text.Trim()))
            {
                MessageBox.Show(FindForm(), FwCoreDlgControls.kstidMissingScrAbbr, caption);
                return(false);
            }
            if (scriptSubtag != null && scriptSubtag.IsPrivateUse)
            {
                if (!LangTagUtils.GetScriptSubtag(scriptSubtag.Code).IsPrivateUse)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidDupScrAbbr, caption);
                    return(false);
                }
                if (!scriptSubtag.IsValid)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidInvalidScrAbbr, caption);
                    return(false);
                }
            }

            RegionSubtag regionSubtag = RegionSubtag;

            // Can't allow a country name without an abbreviation.
            if (regionSubtag == null && !string.IsNullOrEmpty(m_regionName.Text.Trim()))
            {
                MessageBox.Show(FindForm(), FwCoreDlgControls.kstidMissingRgnAbbr, caption);
                return(false);
            }
            if (regionSubtag != null && regionSubtag.IsPrivateUse)
            {
                if (!LangTagUtils.GetRegionSubtag(regionSubtag.Code).IsPrivateUse)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidDupRgnAbbr, caption);
                    return(false);
                }
                if (!regionSubtag.IsValid)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidInvalidRgnAbbr, caption);
                    return(false);
                }
            }

            VariantSubtag variantSubtag = VariantSubtag;

            // Can't allow a variant name without an abbreviation.
            if (variantSubtag == null && !string.IsNullOrEmpty(m_variantName.Text.Trim()))
            {
                MessageBox.Show(FindForm(), FwCoreDlgControls.kstidMissingVarAbbr, caption);
                return(false);
            }
            if (variantSubtag != null && variantSubtag.IsPrivateUse)
            {
                if (!LangTagUtils.GetVariantSubtag(variantSubtag.Code).IsPrivateUse)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidDupVarAbbr, caption);
                    return(false);
                }
                if (!variantSubtag.IsValid)
                {
                    MessageBox.Show(FindForm(), FwCoreDlgControls.kstidInvalidVarAbbr, caption);
                    return(false);
                }
            }
            if (variantSubtag != null)
            {
                var parts = variantSubtag.Code.Split('-').ToList();
                // If these subtags are private use, the first element of each must also be distinct.
                if (m_ws.LanguageSubtag.IsPrivateUse)
                {
                    parts.Add(m_ws.LanguageSubtag.Code.Split('-').First());
                }
                if (scriptSubtag != null && scriptSubtag.IsPrivateUse)
                {
                    parts.Add(scriptSubtag.Code.Split('-').First());
                }
                if (regionSubtag != null && regionSubtag.IsPrivateUse)
                {
                    parts.Add(regionSubtag.Code.Split('-').First());
                }
                var uniqueParts = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                foreach (var part in parts)
                {
                    if (uniqueParts.Contains(part))
                    {
                        MessageBox.Show(FindForm(), String.Format(FwCoreDlgControls.kstidDuplicateParts, part), caption);
                        return(false);
                    }
                    uniqueParts.Add(part);
                }
            }

            return(true);
        }
コード例 #12
0
        public void GetSubtags()
        {
            LanguageSubtag languageSubtag;
            ScriptSubtag   scriptSubtag;
            RegionSubtag   regionSubtag;
            VariantSubtag  variantSubtag;

            Assert.IsTrue(LangTagUtils.GetSubtags("en", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Latn", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Latn", scriptSubtag.Code);
            Assert.IsFalse(scriptSubtag.IsPrivateUse);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-US", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.AreEqual("US", regionSubtag.Code);
            Assert.IsFalse(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Latn-US-fonipa-x-etic", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Latn", scriptSubtag.Code);
            Assert.IsFalse(scriptSubtag.IsPrivateUse);
            Assert.AreEqual("US", regionSubtag.Code);
            Assert.IsFalse(regionSubtag.IsPrivateUse);
            Assert.AreEqual("fonipa-x-etic", variantSubtag.Code);
            Assert.IsFalse(variantSubtag.IsPrivateUse);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-x-kal", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-Qaaa-x-kal-Fake", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Fake", scriptSubtag.Code);
            Assert.IsTrue(scriptSubtag.IsPrivateUse);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-QM-x-kal-XA", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.AreEqual("XA", regionSubtag.Code);
            Assert.IsTrue(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Qaaa-QM-x-Fake-QD", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Fake", scriptSubtag.Code);
            Assert.IsTrue(scriptSubtag.IsPrivateUse);
            Assert.AreEqual("QD", regionSubtag.Code);
            Assert.IsTrue(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsFalse(LangTagUtils.GetSubtags("en_Latn_US_X_ETIC", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));

            // Although dupl0 is in a position where it would normally be interpreted as a private language code, since it isn't a valid one,
            // we instead interpret it as simply a variant of qaa, the unknown language.
            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-x-dupl0", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("qaa", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.IsNull(regionSubtag);
            Assert.That(variantSubtag.Code, Is.EqualTo("x-dupl0"));
            Assert.IsTrue(variantSubtag.IsPrivateUse);
        }
コード例 #13
0
 public void ToIcuLocale_InvalidLangTag()
 {
     LangTagUtils.ToIcuLocale("en_Latn_US_X_ETIC");
 }
コード例 #14
0
 /// <summary>
 ///
 /// </summary>
 internal void VerifyWsId(string wsId)
 {
     //Ensure the writing system identifier is set correctly
     Assert.AreEqual(LangTagUtils.ToLangTag(CurrentWritingSystem.LanguageSubtag, m_regionVariantControl.ScriptSubtag,
                                            m_regionVariantControl.RegionSubtag, m_regionVariantControl.VariantSubtag), wsId);
 }
コード例 #15
0
        public void LanguageAndVariantTags()
        {
            // A new writing system has a Language tag of qaa. This is also its language tag. The others are null.
            var ws = new PalasoWritingSystem();

            VerifySubtagCodes(ws, "qaa", null, null, null, "qaa");
            VerifyComponents(ws, "qaa", "", "", "", "qaa");

            ws.LanguageSubtag = LangTagUtils.GetLanguageSubtag("en");
            VerifySubtagCodes(ws, "en", null, null, null, "en");
            VerifyComponents(ws, "en", "", "", "", "en");
            Assert.That(ws.LanguageName, Is.EqualTo("English"));

            ws.LanguageSubtag = new LanguageSubtag("kal", "Kalaba", true, "");
            Assert.That(ws.LanguageName, Is.EqualTo("Kalaba"));
            VerifySubtagCodes(ws, "kal", null, null, null, "qaa-x-kal");
            VerifyComponents(ws, "qaa", "", "", "x-kal", "qaa-x-kal");
            Assert.That(ws.LanguageSubtag.Name, Is.EqualTo("Kalaba"));

            // This is a region code that is valid, so we don't store it in the private-use area of our code.
            ws.RegionSubtag = LangTagUtils.GetRegionSubtag("QN");
            VerifySubtagCodes(ws, "kal", null, "QN", null, "qaa-QN-x-kal");
            VerifyComponents(ws, "qaa", "", "QN", "x-kal", "qaa-QN-x-kal");

            // This is a standard region (Norway).
            ws.RegionSubtag = LangTagUtils.GetRegionSubtag("NO");
            VerifySubtagCodes(ws, "kal", null, "NO", null, "qaa-NO-x-kal");
            VerifyComponents(ws, "qaa", "", "NO", "x-kal", "qaa-NO-x-kal");

            // A private region
            ws.RegionSubtag = LangTagUtils.GetRegionSubtag("ZD");
            VerifySubtagCodes(ws, "kal", null, "ZD", null, "qaa-QM-x-kal-ZD");
            VerifyComponents(ws, "qaa", "", "QM", "x-kal-ZD", "qaa-QM-x-kal-ZD");

            // Add a private script
            ws.ScriptSubtag = LangTagUtils.GetScriptSubtag("Zfdr");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", null, "qaa-Qaaa-QM-x-kal-Zfdr-ZD");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "x-kal-Zfdr-ZD", "qaa-Qaaa-QM-x-kal-Zfdr-ZD");

            // Change it to a standard one
            ws.ScriptSubtag = LangTagUtils.GetScriptSubtag("Phnx");
            VerifySubtagCodes(ws, "kal", "Phnx", "ZD", null, "qaa-Phnx-QM-x-kal-ZD");
            VerifyComponents(ws, "qaa", "Phnx", "QM", "x-kal-ZD", "qaa-Phnx-QM-x-kal-ZD");

            // To the standard private-use marker
            ws.ScriptSubtag = LangTagUtils.GetScriptSubtag("Qaaa");
            VerifySubtagCodes(ws, "kal", "Qaaa", "ZD", null, "qaa-Qaaa-QM-x-kal-Qaaa-ZD");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "x-kal-Qaaa-ZD", "qaa-Qaaa-QM-x-kal-Qaaa-ZD");


            // Back to the special one
            ws.ScriptSubtag = LangTagUtils.GetScriptSubtag("Zfdr");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", null, "qaa-Qaaa-QM-x-kal-Zfdr-ZD");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "x-kal-Zfdr-ZD", "qaa-Qaaa-QM-x-kal-Zfdr-ZD");

            // Add a standard variant
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("fonipa");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "fonipa", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "fonipa-x-kal-Zfdr-ZD", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD");

            // Change it to a combination one
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("fonipa-x-etic");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "fonipa-x-etic", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-etic");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "fonipa-x-kal-Zfdr-ZD-etic", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-etic");

            // Back to no variant.
            ws.VariantSubtag = null;
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", null, "qaa-Qaaa-QM-x-kal-Zfdr-ZD");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "x-kal-Zfdr-ZD", "qaa-Qaaa-QM-x-kal-Zfdr-ZD");

            // Try a double combination
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("fonipa-1996-x-etic-emic");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "fonipa-1996-x-etic-emic", "qaa-Qaaa-QM-fonipa-1996-x-kal-Zfdr-ZD-etic-emic");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "fonipa-1996-x-kal-Zfdr-ZD-etic-emic", "qaa-Qaaa-QM-fonipa-1996-x-kal-Zfdr-ZD-etic-emic");

            // Drop a piece out of each
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("fonipa-x-etic");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "fonipa-x-etic", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-etic");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "fonipa-x-kal-Zfdr-ZD-etic", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-etic");

            // Soemthing totally unknown
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("fonipa-x-blah");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "fonipa-x-blah", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-blah");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "fonipa-x-kal-Zfdr-ZD-blah", "qaa-Qaaa-QM-fonipa-x-kal-Zfdr-ZD-blah");

            // Drop just the standard part
            ws.VariantSubtag = LangTagUtils.GetVariantSubtag("x-blah");
            VerifySubtagCodes(ws, "kal", "Zfdr", "ZD", "x-blah", "qaa-Qaaa-QM-x-kal-Zfdr-ZD-blah");
            VerifyComponents(ws, "qaa", "Qaaa", "QM", "x-kal-Zfdr-ZD-blah", "qaa-Qaaa-QM-x-kal-Zfdr-ZD-blah");

            // No longer a custom language
            ws.LanguageSubtag = LangTagUtils.GetLanguageSubtag("en");
            VerifySubtagCodes(ws, "en", "Zfdr", "ZD", "x-blah", "en-Qaaa-QM-x-Zfdr-ZD-blah");
            VerifyComponents(ws, "en", "Qaaa", "QM", "x-Zfdr-ZD-blah", "en-Qaaa-QM-x-Zfdr-ZD-blah");

            // No longer a custom script
            ws.ScriptSubtag = null;
            VerifySubtagCodes(ws, "en", null, "ZD", "x-blah", "en-QM-x-ZD-blah");
            VerifyComponents(ws, "en", "", "QM", "x-ZD-blah", "en-QM-x-ZD-blah");

            // No longer a custom region
            ws.RegionSubtag = null;
            VerifySubtagCodes(ws, "en", null, null, "x-blah", "en-x-blah");
            VerifyComponents(ws, "en", "", "", "x-blah", "en-x-blah");

            // No more variant
            ws.VariantSubtag = null;
            VerifySubtagCodes(ws, "en", null, null, null, "en");
            VerifyComponents(ws, "en", "", "", "", "en");
        }
コード例 #16
0
        /// <summary>
        /// Reads the top level special element.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="ws">The ws.</param>
        protected override void ReadTopLevelSpecialElement(XmlReader reader, WritingSystemDefinition ws)
        {
            if (reader.GetAttribute("xmlns:fw") != null)
            {
                reader.ReadStartElement("special");
                var fwWs = (PalasoWritingSystem)ws;
                fwWs.DefaultFontFeatures = GetSpecialValue(reader, "fw", "defaultFontFeatures");
                bool graphiteEnabled;
                if (bool.TryParse(GetSpecialValue(reader, "fw", "graphiteEnabled"), out graphiteEnabled))
                {
                    fwWs.IsGraphiteEnabled = graphiteEnabled;
                }
                fwWs.LegacyMapping       = GetSpecialValue(reader, "fw", "legacyMapping");
                fwWs.MatchedPairs        = GetSpecialValue(reader, "fw", "matchedPairs");
                fwWs.PunctuationPatterns = GetSpecialValue(reader, "fw", "punctuationPatterns");
                fwWs.QuotationMarks      = GetSpecialValue(reader, "fw", "quotationMarks");
                fwWs.RegionName          = GetSpecialValue(reader, "fw", "regionName");
                fwWs.ScriptName          = GetSpecialValue(reader, "fw", "scriptName");
                fwWs.ValidChars          = GetSpecialValue(reader, "fw", "validChars");
                fwWs.VariantName         = GetSpecialValue(reader, "fw", "variantName");
                if (fwWs.VariantName == null)
                {
                    var variant = fwWs.VariantSubtag;
                    if (variant != null)
                    {
                        var stdVariant = LangTagUtils.GetVariantSubtag(variant.Code);
                        if (stdVariant.Name != null)
                        {
                            fwWs.VariantName = stdVariant.Name;
                        }
                        else
                        {
                            var variantName = variant.ToString();
                            if (variantName.StartsWith("x-", StringComparison.OrdinalIgnoreCase))
                            {
                                variantName = variantName.Substring(2);
                            }
                            fwWs.VariantName = variantName;
                        }
                    }
                }
                if (fwWs.RegionName == null)
                {
                    var region = fwWs.RegionSubtag;
                    if (region != null)
                    {
                        var stdRegion = LangTagUtils.GetRegionSubtag(region.Code);
                        if (stdRegion.Name != null)
                        {
                            fwWs.RegionName = stdRegion.Name;
                        }
                        else
                        {
                            var regionName = region.ToString();
                            if (regionName.StartsWith("x-", StringComparison.OrdinalIgnoreCase))
                            {
                                regionName = regionName.Substring(2);
                            }
                            fwWs.RegionName = regionName;
                        }
                    }
                }
                if (fwWs.ScriptName == null)
                {
                    var script = fwWs.ScriptSubtag;
                    if (script != null)
                    {
                        var stdScript = LangTagUtils.GetScriptSubtag(script.Code);
                        if (stdScript.Name != null)
                        {
                            fwWs.ScriptName = stdScript.Name;
                        }
                        else
                        {
                            var scriptName = script.ToString();
                            if (scriptName.StartsWith("x-", StringComparison.OrdinalIgnoreCase))
                            {
                                scriptName = scriptName.Substring(2);
                            }
                            fwWs.ScriptName = scriptName;
                        }
                    }
                }
                var lcidString = GetSpecialValue(reader, "fw", "windowsLCID");
                ((ILegacyWritingSystemDefinition)fwWs).WindowsLcid = lcidString;

                ReadSpecialEndElement(reader);
            }

            else
            {
                base.ReadTopLevelSpecialElement(reader, ws);
            }
        }
コード例 #17
0
        void VerifySubtagCodes(PalasoWritingSystem ws, string langCode, string scriptCode, string regionCode, string variantCode, string id)
        {
            Assert.That(ws.LanguageSubtag.Code, Is.EqualTo(langCode));
            if (scriptCode == null)
            {
                Assert.That(ws.ScriptSubtag, Is.Null);
            }
            else
            {
                Assert.That(ws.ScriptSubtag.Code, Is.EqualTo(scriptCode));
            }
            if (regionCode == null)
            {
                Assert.That(ws.RegionSubtag, Is.Null);
            }
            else
            {
                Assert.That(ws.RegionSubtag.Code, Is.EqualTo(regionCode));
            }
            if (variantCode == null)
            {
                Assert.That(ws.VariantSubtag, Is.Null);
            }
            else
            {
                Assert.That(ws.VariantSubtag.Code, Is.EqualTo(variantCode));
            }

            // Now check that we can get the same tags by parsing the ID.

            LanguageSubtag languageSubtag;
            ScriptSubtag   scriptSubtag;
            RegionSubtag   regionSubtag;
            VariantSubtag  variantSubtag;

            LangTagUtils.GetSubtags(id, out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag);
            Assert.That(languageSubtag.Code, Is.EqualTo(langCode));
            if (scriptCode == null)
            {
                Assert.That(scriptSubtag, Is.Null);
            }
            else
            {
                Assert.That(scriptSubtag.Code, Is.EqualTo(scriptCode));
            }
            if (regionCode == null)
            {
                Assert.That(regionSubtag, Is.Null);
            }
            else
            {
                Assert.That(regionSubtag.Code, Is.EqualTo(regionCode));
            }
            if (variantCode == null)
            {
                Assert.That(variantSubtag, Is.Null);
            }
            else
            {
                Assert.That(variantSubtag.Code, Is.EqualTo(variantCode));
            }
        }
コード例 #18
0
        public void GetSubtags()
        {
            LanguageSubtag languageSubtag;
            ScriptSubtag   scriptSubtag;
            RegionSubtag   regionSubtag;
            VariantSubtag  variantSubtag;

            Assert.IsTrue(LangTagUtils.GetSubtags("en", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Latn", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Latn", scriptSubtag.Code);
            Assert.IsFalse(scriptSubtag.IsPrivateUse);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-US", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.AreEqual("US", regionSubtag.Code);
            Assert.IsFalse(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Latn-US-fonipa-x-etic", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Latn", scriptSubtag.Code);
            Assert.IsFalse(scriptSubtag.IsPrivateUse);
            Assert.AreEqual("US", regionSubtag.Code);
            Assert.IsFalse(regionSubtag.IsPrivateUse);
            Assert.AreEqual("fonipa-x-etic", variantSubtag.Code);
            Assert.IsFalse(variantSubtag.IsPrivateUse);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-x-kal", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-Qaaa-x-kal-Fake", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Fake", scriptSubtag.Code);
            Assert.IsTrue(scriptSubtag.IsPrivateUse);
            Assert.IsNull(regionSubtag);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("qaa-QM-x-kal-XA", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("kal", languageSubtag.Code);
            Assert.IsTrue(languageSubtag.IsPrivateUse);
            Assert.IsNull(scriptSubtag);
            Assert.AreEqual("XA", regionSubtag.Code);
            Assert.IsTrue(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsTrue(LangTagUtils.GetSubtags("en-Qaaa-QM-x-Fake-QD", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
            Assert.AreEqual("en", languageSubtag.Code);
            Assert.IsFalse(languageSubtag.IsPrivateUse);
            Assert.AreEqual("Fake", scriptSubtag.Code);
            Assert.IsTrue(scriptSubtag.IsPrivateUse);
            Assert.AreEqual("QD", regionSubtag.Code);
            Assert.IsTrue(regionSubtag.IsPrivateUse);
            Assert.IsNull(variantSubtag);

            Assert.IsFalse(LangTagUtils.GetSubtags("en_Latn_US_X_ETIC", out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag));
        }