public void Test4052223() { ParsePosition pos = new ParsePosition(0); if (pos.ErrorIndex != -1) { Errln("ParsePosition.getErrorIndex initialization failed."); } MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree."); String str = "There is one apple growing on the peach tree."; Object[] objs = fmt.Parse(str, pos); Logln("unparsable string , should fail at " + pos.ErrorIndex); if (pos.ErrorIndex == -1) { Errln("Bug 4052223 failed : parsing string " + str); } pos.ErrorIndex = (4); if (pos.ErrorIndex != 4) { Errln("setErrorIndex failed, got " + pos.ErrorIndex + " instead of 4"); } if (objs != null) { Errln("objs should be null"); } ChoiceFormat f = new ChoiceFormat( "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2."); pos.Index = (0); pos.ErrorIndex = (-1); /*Number*/ object obj = f.Parse("are negative", pos); if (pos.ErrorIndex != -1 && Convert.ToDouble(obj) == -1.0) { Errln("Parse with \"are negative\" failed, at " + pos.ErrorIndex); } pos.Index = (0); pos.ErrorIndex = (-1); obj = f.Parse("are no or fraction ", pos); if (pos.ErrorIndex != -1 && Convert.ToDouble(obj) == 0.0) { Errln("Parse with \"are no or fraction\" failed, at " + pos.ErrorIndex); } pos.Index = (0); pos.ErrorIndex = (-1); obj = f.Parse("go postal", pos); if (pos.ErrorIndex == -1 && !double.IsNaN(Convert.ToDouble(obj))) { Errln("Parse with \"go postal\" failed, at " + pos.ErrorIndex); } }
public void Test_parseLjava_lang_StringLjava_text_ParsePosition() { // Test for method java.lang.Number // java.text.ChoiceFormat.parse(java.lang.String, // java.text.ParsePosition) ChoiceFormat format = new ChoiceFormat("1#one|2#two|3#three"); NUnit.Framework.Assert.AreEqual(Double.NaN, System.Convert.ToDouble(format.Parse("One", new ParsePosition(0))), "Case insensitive"); ParsePosition pos = new ParsePosition(0); object result = f1.Parse("Greater than two", pos); NUnit.Framework.Assert.IsTrue(result is Double, "Not a Double1"); NUnit.Framework.Assert.IsTrue(Convert.ToDouble(result) == ChoiceFormat.NextDouble(2), "Wrong value ~>2"); NUnit.Framework.Assert.AreEqual(16, pos.GetIndex(), "Wrong position ~16"); pos = new ParsePosition(0); NUnit.Framework.Assert.IsTrue(Double.IsNaN(Convert.ToDouble(f1.Parse("12one", pos))), "Incorrect result"); NUnit.Framework.Assert.AreEqual(0, pos.GetIndex(), "Wrong position ~0"); pos = new ParsePosition(2); result = f1.Parse("12one and two", pos); NUnit.Framework.Assert.IsTrue(result is Double, "Not a Double2"); NUnit.Framework.Assert.AreEqual(1.0D, Convert.ToDouble(result), 0.0D, "Ignored parse position"); NUnit.Framework.Assert.AreEqual(5, pos.GetIndex(), "Wrong position ~5"); }
/// <exclude/> /// <summary> /// Attempt to parse the given string as a currency, either as a display name /// in the given locale, or as a 3-letter ISO 4217 code. If multiple display /// names match, then the longest one is selected. If both a display name and /// a 3-letter ISO code match, then the display name is preferred, unless /// it's length is less than 3. /// </summary> /// /// <param name="locale">the locale of the display names to match</param> /// <param name="text">the text to parse</param> /// <param name="pos">input-output position; on input, the position within text tomatch; must have 0 <= pos.getIndex() < text.length(); onoutput, the position after the last matched character. If theparse fails, the position in unchanged upon output.</param> /// <returns>the ISO 4217 code, as a string, of the best match, or null if /// there is no match</returns> public static String Parse(ULocale locale, String text, ILOG.J2CsMapping.Text.ParsePosition pos) { // TODO: There is a slight problem with the pseudo-multi-level // fallback implemented here. More-specific locales don't // properly shield duplicate entries in less-specific locales. // This problem will go away when real multi-level fallback is // implemented. We could also fix this by recording (in a // hash) which codes are used at each level of fallback, but // this doesn't seem warranted. int start = pos.GetIndex(); String fragment = text.Substring(start); String iso = null; int max = 0; // Look up the Currencies resource for the given locale. The // Currencies locale data looks like this: // |en { // | Currencies { // | USD { "US$", "US Dollar" } // | CHF { "Sw F", "Swiss Franc" } // | INR { "=0#Rs|1#Re|1<Rs", "=0#Rupees|1#Rupee|1<Rupees" } // | //... // | } // |} // In the future, resource bundles may implement multi-level // fallback. That is, if a currency is not found in the en_US // Currencies data, then the en Currencies data will be searched. // Currently, if a Currencies datum exists in en_US and en, the // en_US entry hides that in en. // We want multi-level fallback for this resource, so we implement // it manually. // Multi-level resource inheritance fallback loop while (locale != null) { UResourceBundle rb = IBM.ICU.Util.UResourceBundle.GetBundleInstance( IBM.ICU.Impl.ICUResourceBundle.ICU_BASE_NAME, locale); // We can't cast this to String[][]; the cast has to happen later try { UResourceBundle currencies = rb.Get("Currencies"); // Do a linear search for (int i = 0; i < currencies.GetSize(); ++i) { // String name = ((String[]) currencies[i][1])[0]; UResourceBundle item = currencies.Get(i); String name = item.GetString(0); if (name.Length < 1) { // Ignore zero-length names -- later, change this // when zero-length is used to mean something. continue; } else if (name[0] == '=') { name = name.Substring(1); if (name.Length > 0 && name[0] != '=') { ChoiceFormat choice = new ChoiceFormat(name); // Number n = choice.Parse(text, pos); int len = pos.GetIndex() - start; if (len > max) { iso = item.GetKey(); max = len; } pos.SetIndex(start); continue; } } if (name.Length > max && fragment.StartsWith(name)) { iso = item.GetKey(); max = name.Length; } } } catch (MissingManifestResourceException e) { } locale = locale.GetFallback(); } /* * 1. Look at the Currencies array from the locale 1a. Iterate through * it, and check each row to see if row[1] matches 1a1. If row[1] is a * pattern, use ChoiceFormat to attempt a parse 1b. Upon a match, return * the ISO code stored at row[0] 2. If there is no match, fall back to * "en" and try again 3. If there is no match, fall back to root and try * again 4. If still no match, parse 3-letter ISO {this code is probably * unchanged}. * * ICUResourceBundle rb = * (ICUResourceBundle)UResourceBundle.getBundleInstance * (UResourceBundle.ICU_BASE_NAME, locale); ICUResourceBundle currencies * = rb.get("Currencies"); */ // If display name parse fails or if it matches fewer than 3 // characters, try to parse 3-letter ISO. Do this after the // display name processing so 3-letter display names are // preferred. Consider /[A-Z]{3}/ to be valid ISO, and parse // it manually--UnicodeSet/regex are too slow and heavy. if (max < 3 && (text.Length - start) >= 3) { bool valid = true; for (int k = 0; k < 3; ++k) { char ch = text[start + k]; // 16-bit ok if (ch < 'A' || ch > 'Z') { valid = false; break; } } if (valid) { iso = text.Substring(start, (start + 3) - (start)); max = 3; } } pos.SetIndex(start + max); return(iso); }