/// <summary> /// Creates a formatter from the pattern string. /// The number of arguments checked against the given limits is the /// highest argument number plus one, not the number of occurrences of arguments. /// </summary> /// <param name="pattern">The pattern string.</param> /// <param name="min">The pattern must have at least this many arguments.</param> /// <param name="max">The pattern must have at most this many arguments.</param> /// <returns>The new <see cref="SimpleFormatter"/> object.</returns> /// <exception cref="ArgumentException">For bad argument syntax and too few or too many arguments.</exception> /// <stable>ICU 57</stable> public static SimpleFormatter CompileMinMaxArguments(StringBuilder pattern, int min, int max) { StringBuilder sb = new StringBuilder(); string compiledPattern = SimpleFormatterImpl.CompileToStringMinMaxArguments(pattern, sb, min, max); return(new SimpleFormatter(compiledPattern)); }
private StringBuilder AppendWithSep(string s, StringBuilder b) { if (b.Length == 0) { b.Append(s); } else { SimpleFormatterImpl.FormatAndReplace(separatorFormat, b, null, b.AsCharSequence(), s.AsCharSequence()); } return(b); }
// ICU4N specific - Format(params ICharSequence[] values) moved to SimpleFormatterExtension.tt // ICU4N specific - FormatAndAppend( // StringBuilder appendTo, int[] offsets, params ICharSequence[] values) moved to SimpleFormatterExtension.tt /// <summary> /// Formats the given values, appending to the <paramref name="appendTo"/> builder. /// </summary> /// <param name="appendTo">Gets the formatted pattern and values appended.</param> /// <param name="offsets"> /// offsets[i] receives the offset of where /// values[i] replaced pattern argument {i}. /// Can be null, or can be shorter or longer than values. /// If there is no {i} in the pattern, then offsets[i] is set to -1. /// </param> /// <returns><paramref name="appendTo"/></returns> /// <stable>ICU4N 60.1</stable> public StringBuilder FormatAndAppend( StringBuilder appendTo, int[] offsets) // ICU4N specific overload to avoid ambiguity when no params are passed { return(SimpleFormatterImpl.FormatAndAppend(compiledPattern, appendTo, offsets, new ICharSequence[0])); }
/// <summary> /// Returns the pattern text with none of the arguments. /// Like formatting with all-empty string values. /// </summary> /// <stable>ICU 57</stable> public string GetTextWithNoArguments() { return(SimpleFormatterImpl.GetTextWithNoArguments(compiledPattern)); }
/// <summary> /// Formats the given values, replacing the contents of the result builder. /// May optimize by actually appending to the result if it is the same object /// as the value corresponding to the initial argument in the pattern. /// </summary> /// <param name="result">Gets its contents replaced by the formatted pattern and values.</param> /// <param name="offsets"> /// offsets[i] receives the offset of where /// values[i] replaced pattern argument {i}. /// Can be null, or can be shorter or longer than values. /// If there is no {i} in the pattern, then offsets[i] is set to -1. /// </param> /// <param name="values"> /// The argument values. /// An argument value may be the same object as result. /// values.Length must be at least <see cref="ArgumentLimit"/>. /// </param> /// <returns><paramref name="result"/></returns> /// <stable>ICU 57</stable> internal StringBuilder FormatAndReplace( StringBuilder result, int[] offsets, params ICharSequence[] values) { return(SimpleFormatterImpl.FormatAndReplace(compiledPattern, result, offsets, values)); }
public StringBuilder FormatAndReplace( StringBuilder result, int[] offsets, params char[][] values) { return(SimpleFormatterImpl.FormatAndReplace(compiledPattern, result, offsets, values)); }
/// <summary> /// Formats the given values, appending to the <paramref name="appendTo"/> builder. /// </summary> /// <param name="appendTo">Gets the formatted pattern and values appended.</param> /// <param name="offsets"> /// offsets[i] receives the offset of where /// values[i] replaced pattern argument {i}. /// Can be null, or can be shorter or longer than values. /// If there is no {i} in the pattern, then offsets[i] is set to -1. /// </param> /// <param name="values"> /// The argument values. /// An argument value must not be the same object as appendTo. /// values.Length must be at least <see cref="ArgumentLimit"/>. /// Can be null if <see cref="ArgumentLimit"/>==0. /// </param> /// <returns><paramref name="appendTo"/></returns> /// <stable>ICU 57</stable> internal StringBuilder FormatAndAppend( StringBuilder appendTo, int[] offsets, params ICharSequence[] values) { return(SimpleFormatterImpl.FormatAndAppend(compiledPattern, appendTo, offsets, values)); }
public StringBuilder FormatAndAppend( StringBuilder appendTo, int[] offsets, params char[][] values) { return(SimpleFormatterImpl.FormatAndAppend(compiledPattern, appendTo, offsets, values)); }
/// <summary> /// Formats the given values. /// </summary> /// <stable>ICU 57</stable> internal string Format(params ICharSequence[] values) { return(SimpleFormatterImpl.FormatCompiledPattern(compiledPattern, values)); }
public string Format(params char[][] values) { return(SimpleFormatterImpl.FormatCompiledPattern(compiledPattern, values)); }
// TODO: implement use of capitalization private string GetLocaleDisplayNameInternal(UCultureInfo locale) { // lang // lang (script, country, variant, keyword=value, ...) // script, country, variant, keyword=value, ... string resultName = null; string lang = locale.Language; // Empty basename indicates root locale (keywords are ignored for this). // Our data uses 'root' to access display names for the root locale in the // "Languages" table. if (locale.Name.Length == 0) { lang = "root"; } string script = locale.Script; string country = locale.Country; string variant = locale.Variant; bool hasScript = script.Length > 0; bool hasCountry = country.Length > 0; bool hasVariant = variant.Length > 0; // always have a value for lang if (displayContextOptions.DialectHandling == DialectHandling.DialectNames) { do { // loop construct is so we can break early out of search if (hasScript && hasCountry) { string langScriptCountry = lang + '_' + script + '_' + country; string result = LocaleIdName(langScriptCountry); if (result != null && !result.Equals(langScriptCountry)) { resultName = result; hasScript = false; hasCountry = false; break; } } if (hasScript) { string langScript = lang + '_' + script; string result = LocaleIdName(langScript); if (result != null && !result.Equals(langScript)) { resultName = result; hasScript = false; break; } } if (hasCountry) { string langCountry = lang + '_' + country; string result = LocaleIdName(langCountry); if (result != null && !result.Equals(langCountry)) { resultName = result; hasCountry = false; break; } } } while (false); } if (resultName == null) { string result = LocaleIdName(lang); if (result == null) { return(null); } resultName = result .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen); } StringBuilder buf = new StringBuilder(); if (hasScript) { // first element, don't need appendWithSep string result = GetScriptDisplayNameInContext(script, true); if (result == null) { return(null); } buf.Append(result .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen)); } if (hasCountry) { string result = GetRegionDisplayName(country, true); if (result == null) { return(null); } AppendWithSep(result .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen), buf); } if (hasVariant) { string result = GetVariantDisplayName(variant, true); if (result == null) { return(null); } AppendWithSep(result .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen), buf); } using (var pairs = locale.Keywords.GetEnumerator()) { if (pairs != null) { while (pairs.MoveNext()) { string key = pairs.Current.Key; string value = pairs.Current.Value; // locale.GetKeywordValue(key); string keyDisplayName = GetKeyDisplayName(key, true); if (keyDisplayName == null) { return(null); } keyDisplayName = keyDisplayName .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen); string valueDisplayName = GetKeyValueDisplayName(key, value, true); if (valueDisplayName == null) { return(null); } valueDisplayName = valueDisplayName .Replace(formatOpenParen, formatReplaceOpenParen) .Replace(formatCloseParen, formatReplaceCloseParen); if (!valueDisplayName.Equals(value)) { AppendWithSep(valueDisplayName, buf); } else if (!key.Equals(keyDisplayName)) { string keyValue = SimpleFormatterImpl.FormatCompiledPattern( keyTypeFormat, keyDisplayName, valueDisplayName); AppendWithSep(keyValue, buf); } else { AppendWithSep(keyDisplayName, buf) .Append("=") .Append(valueDisplayName); } } } } string resultRemainder = null; if (buf.Length > 0) { resultRemainder = buf.ToString(); } if (resultRemainder != null) { resultName = SimpleFormatterImpl.FormatCompiledPattern( format, resultName, resultRemainder); } return(AdjustForUsageAndContext(CapitalizationContextUsage.Language, resultName)); }
public DataTableCultureDisplayNames(UCultureInfo culture, DisplayContextOptions options) #pragma warning disable 612, 618 : base() #pragma warning restore 612, 618 { this.displayContextOptions = options.Freeze(); this.langData = languageDataTableProvider.GetDataTable(culture, options.SubstituteHandling == SubstituteHandling.NoSubstitute); this.regionData = regionDataTableProvider.GetDataTable(culture, options.SubstituteHandling == SubstituteHandling.NoSubstitute); this.locale = langData.CultureInfo != null && langData.CultureInfo.Equals(CultureInfo.InvariantCulture) ? regionData.CultureInfo.ToUCultureInfo() : langData.CultureInfo.ToUCultureInfo(); // Note, by going through DataTable, this uses table lookup rather than straight lookup. // That should get us the same data, I think. This way we don't have to explicitly // load the bundle again. Using direct lookup didn't seem to make an appreciable // difference in performance. string sep = langData.Get("localeDisplayPattern", "separator"); if (sep == null || "separator".Equals(sep)) { sep = "{0}, {1}"; } StringBuilder sb = new StringBuilder(); this.separatorFormat = SimpleFormatterImpl.CompileToStringMinMaxArguments(sep, sb, 2, 2); string pattern = langData.Get("localeDisplayPattern", "pattern"); if (pattern == null || "pattern".Equals(pattern)) { pattern = "{0} ({1})"; } this.format = SimpleFormatterImpl.CompileToStringMinMaxArguments(pattern, sb, 2, 2); if (pattern.Contains("(")) { formatOpenParen = '('; formatCloseParen = ')'; formatReplaceOpenParen = '['; formatReplaceCloseParen = ']'; } else { formatOpenParen = '('; formatCloseParen = ')'; formatReplaceOpenParen = '['; formatReplaceCloseParen = ']'; } string keyTypePattern = langData.Get("localeDisplayPattern", "keyTypePattern"); if (keyTypePattern == null || "keyTypePattern".Equals(keyTypePattern)) { keyTypePattern = "{0}={1}"; } this.keyTypeFormat = SimpleFormatterImpl.CompileToStringMinMaxArguments( keyTypePattern, sb, 2, 2); // Get values from the contextTransforms data if we need them // Also check whether we will need a break iterator (depends on the data) bool needBrkIter = false; if (options.Capitalization == Capitalization.UIListOrMenu || options.Capitalization == Capitalization.Standalone) { capitalizationUsage = new bool[Enum.GetValues(typeof(CapitalizationContextUsage)).Length]; // initialized to all false ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.GetBundleInstance(ICUData.IcuBaseName, locale); CapitalizationContextSink sink = new CapitalizationContextSink(this); try { rb.GetAllItemsWithFallback("contextTransforms", sink); } catch (MissingManifestResourceException) { // Silently ignore. Not every locale has contextTransforms. } needBrkIter = sink.hasCapitalizationUsage; } // Get a sentence break iterator if we will need it if (needBrkIter || options.Capitalization == Capitalization.BeginningOfSentence) { capitalizationBrkIter = BreakIterator.GetSentenceInstance(locale); } this.currencyDisplayInfo = CurrencyData.Provider.GetInstance(locale, false); }