/// <summary> /// Attempt to find a source-target/variant in the static locale resource /// store. Do not perform fallback. Return 0 on failure. /// 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(TransliteratorRegistry.Spec src, TransliteratorRegistry.Spec trg, String variant) { if (DEBUG) { String ID_0 = IBM.ICU.Text.TransliteratorIDParser.STVtoID(src.Get(), trg.Get(), variant); System.Console.Out .WriteLine("TransliteratorRegistry.findInStaticStore:" + ID_0); } Object[] entry = null; if (src.IsLocale()) { entry = FindInBundle(src, trg, variant, IBM.ICU.Text.Transliterator.FORWARD); } else if (trg.IsLocale()) { entry = FindInBundle(trg, src, variant, IBM.ICU.Text.Transliterator.REVERSE); } // If we found an entry, store it in the Hashtable for next // time. if (entry != null) { RegisterEntry(src.GetTop(), trg.GetTop(), variant, entry, false); } return(entry); }
/// <summary> /// Top-level find method. Attempt to find a source-target/variant in either /// the dynamic or the static (locale resource) store. Perform fallback. /// Lookup sequence for ss_SS_SSS-tt_TT_TTT/v: /// ss_SS_SSS-tt_TT_TTT/v -- in hashtable ss_SS_SSS-tt_TT_TTT/v -- in /// ss_SS_SSS (no fallback) /// repeat with t = tt_TT_TTT, tt_TT, tt, and tscript /// ss_SS_SSS-t//// ss_SS-t//// ss-t//// sscript-t/ /// Here/// matches the first variant listed. /// Caller does NOT own returned object. Return 0 on failure. /// </summary> /// private Object[] Find(String source, String target, String variant) { TransliteratorRegistry.Spec src = new TransliteratorRegistry.Spec(source); TransliteratorRegistry.Spec trg = new TransliteratorRegistry.Spec(target); Object[] entry = null; if (variant.Length != 0) { // Seek exact match in hashtable entry = FindInDynamicStore(src, trg, variant); if (entry != null) { return(entry); } // Seek exact match in locale resources entry = FindInStaticStore(src, trg, variant); if (entry != null) { return(entry); } } for (;;) { src.Reset(); for (;;) { // Seek match in hashtable entry = FindInDynamicStore(src, trg, NO_VARIANT); if (entry != null) { return(entry); } // Seek match in locale resources entry = FindInStaticStore(src, trg, NO_VARIANT); if (entry != null) { return(entry); } if (!src.HasFallback()) { break; } src.Next(); } if (!trg.HasFallback()) { break; } trg.Next(); } return(null); }
/// <summary> /// Attempt to find a source-target/variant in the dynamic registry store. /// Return 0 on failure. /// </summary> /// private Object[] FindInDynamicStore(TransliteratorRegistry.Spec src, TransliteratorRegistry.Spec trg, String variant) { String ID_0 = IBM.ICU.Text.TransliteratorIDParser.STVtoID(src.Get(), trg.Get(), variant); if (DEBUG) { System.Console.Out.WriteLine("TransliteratorRegistry.findInDynamicStore:" + ID_0); } return((Object[])registry[new CaseInsensitiveString(ID_0)]); }
/// <summary> /// Attempt to find an entry in a single resource bundle. This is a one-sided /// lookup. findInStaticStore() performs up to two such lookups, one for the /// source, and one for the target. /// Do not perform fallback. Return 0 on failure. /// On success, create a new Entry object, populate it, and return it. The /// caller owns the returned object. /// </summary> /// private Object[] FindInBundle(TransliteratorRegistry.Spec specToOpen, TransliteratorRegistry.Spec specToFind, String variant, int direction_0) { // assert(specToOpen.isLocale()); ResourceBundle res_1 = specToOpen.GetBundle(); if (res_1 == 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_0 == IBM.ICU.Text.Transliterator.FORWARD) ? "TransliterateTo" : "TransliterateFrom"); } else { tag.Append("Transliterate"); } tag.Append(specToFind.Get().ToUpper()); 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_1.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.InvariantCultureIgnoreCase)) { 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. int dir = (pass == 0) ? IBM.ICU.Text.Transliterator.FORWARD : direction_0; return(new Object[] { new TransliteratorRegistry.LocaleEntry(subres[i + 1], dir) }); } } catch (MissingManifestResourceException e) { if (DEBUG) { System.Console.Out.WriteLine("missing resource: " + e); } } } // If we get here we had a missing resource exception or we // failed to find a desired variant. return(null); }