private static string ToID(IDictionary <char, Extension> map) { StringBuilder buf = new StringBuilder(); Extension privuse = null; foreach (var entry in map) { char singleton = entry.Key; Extension extension = entry.Value; if (LanguageTag.IsPrivateusePrefixChar(singleton)) { privuse = extension; } else { if (buf.Length > 0) { buf.Append(LanguageTag.Separator); } buf.Append(extension); } } if (privuse != null) { if (buf.Length > 0) { buf.Append(LanguageTag.Separator); } buf.Append(privuse); } return(buf.ToString()); }
public InternalLocaleBuilder SetExtension(char singleton, string value) { // validate key bool isBcpPrivateuse = LanguageTag.IsPrivateusePrefixChar(singleton); if (!isBcpPrivateuse && !LanguageTag.IsExtensionSingletonChar(singleton)) { throw new FormatException("Ill-formed extension key: " + singleton); } bool remove = (value == null || value.Length == 0); CaseInsensitiveChar key = new CaseInsensitiveChar(singleton); if (remove) { if (UnicodeLocaleExtension.IsSingletonChar(key.Value)) { // clear entire Unicode locale extension if (_uattributes != null) { _uattributes.Clear(); } if (_ukeywords != null) { _ukeywords.Clear(); } } else { if (_extensions != null && _extensions.ContainsKey(key)) { _extensions.Remove(key); } } } else { // validate value string val = value.Replace(BaseLocale.Separator, LanguageTag.Separator); StringTokenEnumerator itr = new StringTokenEnumerator(val, LanguageTag.Separator); while (itr.MoveNext()) { string s = itr.Current; bool validSubtag; if (isBcpPrivateuse) { validSubtag = LanguageTag.IsPrivateuseSubtag(s); } else { validSubtag = LanguageTag.IsExtensionSubtag(s); } if (!validSubtag) { throw new FormatException("Ill-formed extension value: " + s /*, itr.CurrentStart*/); } } if (UnicodeLocaleExtension.IsSingletonChar(key.Value)) { SetUnicodeLocaleExtension(val); } else { if (_extensions == null) { _extensions = new Dictionary <CaseInsensitiveChar, string>(4); } _extensions[key] = val; } } return(this); }
/// <summary> /// Internal constructor, only used by <see cref="InternalLocaleBuilder"/>. /// </summary> internal LocaleExtensions(IDictionary <CaseInsensitiveChar, string> extensions, ISet <CaseInsensitiveString> uattributes, IDictionary <CaseInsensitiveString, string> ukeywords) { bool hasExtension = (extensions != null && extensions.Count > 0); bool hasUAttributes = (uattributes != null && uattributes.Count > 0); bool hasUKeywords = (ukeywords != null && ukeywords.Count > 0); if (!hasExtension && !hasUAttributes && !hasUKeywords) { _map = EmptyMap; _id = ""; return; } // Build extension map _map = new JCG.SortedDictionary <char, Extension>(); if (hasExtension) { foreach (var ext in extensions) { char key = AsciiUtil.ToLower(ext.Key.Value); string value = ext.Value; if (LanguageTag.IsPrivateusePrefixChar(key)) { // we need to exclude special variant in privuateuse, e.g. "x-abc-lvariant-DEF" value = InternalLocaleBuilder.RemovePrivateuseVariant(value); if (value == null) { continue; } } Extension e = new Extension(key, AsciiUtil.ToLower(value)); _map[key] = e; } } if (hasUAttributes || hasUKeywords) { JCG.SortedSet <string> uaset = null; JCG.SortedDictionary <string, string> ukmap = null; if (hasUAttributes) { uaset = new JCG.SortedSet <string>(StringComparer.Ordinal); foreach (CaseInsensitiveString cis in uattributes) { uaset.Add(AsciiUtil.ToLower(cis.Value)); } } if (hasUKeywords) { ukmap = new JCG.SortedDictionary <string, string>(StringComparer.Ordinal); foreach (var kwd in ukeywords) { string key = AsciiUtil.ToLower(kwd.Key.Value); string type = AsciiUtil.ToLower(kwd.Value); ukmap[key] = type; } } UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap); _map[UnicodeLocaleExtension.Singleton] = ule; } if (_map.Count == 0) { // this could happen when only privuateuse with special variant _map = EmptyMap; _id = ""; } else { _id = ToID(_map); } }
public static bool IsValidKey(char c) { return(LanguageTag.IsExtensionSingletonChar(c) || LanguageTag.IsPrivateusePrefixChar(c)); }