/// <summary> /// Attempt to find a source-target/variant in the static locale /// resource store. Do not perform fallback. Return 0 on failure. /// <para/> /// On success, create a new entry object, register it in the dynamic /// store, and return a pointer to it, but do not make it public -- /// just because someone requested something, we do not expand the /// available ID list (or spec DAG). /// </summary> private object[] FindInStaticStore(Spec src, Spec trg, string variant) { ////CLOVER:OFF if (DEBUG) { string ID = TransliteratorIDParser.STVtoID(src.Get(), trg.Get(), variant); Console.Out.WriteLine("TransliteratorRegistry.findInStaticStore:" + ID); } ////CLOVER:ON object[] entry = null; if (src.IsLocale) { entry = FindInBundle(src, trg, variant, Transliterator.Forward); } else if (trg.IsLocale) { entry = FindInBundle(trg, src, variant, Transliterator.Reverse); } // If we found an entry, store it in the Hashtable for next // time. if (entry != null) { RegisterEntry(src.Top, trg.Top, variant, entry, false); } return(entry); }
/// <summary> /// Attempt to find a source-target/variant in the dynamic registry /// store. Return 0 on failure. /// </summary> private object[] FindInDynamicStore(Spec src, Spec trg, string variant) { string ID = TransliteratorIDParser.STVtoID(src.Get(), trg.Get(), variant); ////CLOVER:OFF if (DEBUG) { Console.Out.WriteLine("TransliteratorRegistry.findInDynamicStore:" + ID); } ////CLOVER:ON return(registry.Get(new CaseInsensitiveString(ID))); }
/// <summary> /// Attempt to find an entry in a single resource bundle. This is /// a one-sided lookup. <see cref="FindInStaticStore(Spec, Spec, string)"/> performs up to two such /// lookups, one for the source, and one for the target. /// <para/> /// Do not perform fallback. Return 0 on failure. /// <para/> /// On success, create a new Entry object, populate it, and return it. /// The caller owns the returned object. /// </summary> private object[] FindInBundle(Spec specToOpen, Spec specToFind, string variant, TransliterationDirection direction) { // assert(specToOpen.isLocale()); ResourceBundle res = specToOpen.GetBundle(); if (res == null) { // This means that the bundle's locale does not match // the current level of iteration for the spec. return(null); } for (int pass = 0; pass < 2; ++pass) { StringBuilder tag = new StringBuilder(); // First try either TransliteratorTo_xxx or // TransliterateFrom_xxx, then try the bidirectional // Transliterate_xxx. This precedence order is arbitrary // but must be consistent and documented. if (pass == 0) { tag.Append(direction == Transliterator.Forward ? "TransliterateTo" : "TransliterateFrom"); } else { tag.Append("Transliterate"); } tag.Append(specToFind.Get().ToUpperInvariant()); try { // The Transliterate*_xxx resource is an array of // strings of the format { <v0>, <r0>, ... }. Each // <vi> is a variant name, and each <ri> is a rule. string[] subres = res.GetStringArray(tag.ToString()); // assert(subres != null); // assert(subres.length % 2 == 0); int i = 0; if (variant.Length != 0) { for (i = 0; i < subres.Length; i += 2) { if (subres[i].Equals(variant, StringComparison.OrdinalIgnoreCase)) { break; } } } if (i < subres.Length) { // We have a match, or there is no variant and i == 0. // We have succeeded in loading a string from the // locale resources. Return the rule string which // will itself become the registry entry. // The direction is always forward for the // TransliterateTo_xxx and TransliterateFrom_xxx // items; those are unidirectional forward rules. // For the bidirectional Transliterate_xxx items, // the direction is the value passed in to this // function. TransliterationDirection dir = (pass == 0) ? Transliterator.Forward : direction; return(new Object[] { new LocaleEntry(subres[i + 1], dir) }); } } catch (MissingManifestResourceException e) { ////CLOVER:OFF if (DEBUG) { Console.Out.WriteLine("missing resource: " + e); } ////CLOVER:ON } } // If we get here we had a missing resource exception or we // failed to find a desired variant. return(null); }