static internal bool UpTo(String str0, ParsePosition position, StringBuilder buffer, char stop) { int index = position.GetIndex(), length = str0.Length; bool lastQuote = false, quote = false; while (index < length) { char ch = str0[index++]; if (ch == '\'') { if (lastQuote) { buffer.Append('\''); } quote = !quote; lastQuote = true; } else if (ch == stop && !quote) { position.SetIndex(index); return(true); } else { lastQuote = false; buffer.Append(ch); } } position.SetIndex(index); return(false); }
static internal bool UpToWithQuotes(String str0, ParsePosition position, StringBuilder buffer, char stop, char start) { int index = position.GetIndex(), length = str0.Length, count = 1; bool quote = false; while (index < length) { char ch = str0[index++]; if (ch == '\'') { quote = !quote; } if (!quote) { if (ch == stop) { count--; } if (count == 0) { position.SetIndex(index); return(true); } if (ch == start) { count++; } } buffer.Append(ch); } // text.07=Unmatched braces in the pattern throw new ArgumentException("text.07"); //$NON-NLS-1$ }
/// <summary> /// Parse a Double from the specified String starting at the index specified /// by the ParsePosition. The String is compared to the strings of this /// ChoiceFormat and if a match occurs, the answer is the lower bound of the /// corresponding range. If the string is successfully parsed, the index of /// the ParsePosition is updated to the index following the parsed text. /// </summary> /// /// <param name="string">the String to parse</param> /// <param name="position">the ParsePosition, updated on return with the index followingthe parsed text, or on error the index is unchanged and theerror index is set to the index where the error occurred</param> /// <returns>a Double resulting from the parse, or Double.NaN if there is an /// error</returns> public override object Parse(String str0, ParsePosition position) { int offset = position.GetIndex(); for (int i = 0; i < choiceFormats.Length; i++) { if (ILOG.J2CsMapping.Util.StringUtil.StartsWith(str0, choiceFormats[i], offset)) { position.SetIndex(offset + choiceFormats[i].Length); return((double)(choiceLimits[i])); } } position.SetErrorIndex(offset); return((double)(System.Double.NaN)); }
/* * Note: This method only parse integer numbers which can be represented by * long */ public override object Parse(String text, ParsePosition parsePosition) { long num = 0; bool sawNumber = false; bool negative = false; int bs = parsePosition.GetIndex(); int offset = 0; for (; bs + offset < text.Length; offset++) { char ch = text[bs + offset]; if (offset == 0 && ch == minusSign) { if (positiveOnly) { break; } negative = true; } else { int digit = ch - zeroDigit; if (digit < 0 || 9 < digit) { digit = IBM.ICU.Lang.UCharacter.Digit(ch); } if (0 <= digit && digit <= 9) { sawNumber = true; num = num * 10 + digit; } else { break; } } } object result = null; if (sawNumber) { num = (negative) ? num * (-1) : num; result = (long)(num); parsePosition.SetIndex(bs + offset); } return(result); }
private int Match(String str0, ParsePosition position, bool last, String[] tokens) { int length = str0.Length, offset = position.GetIndex(), token = -1; while (offset < length && Char.IsWhiteSpace(str0[offset])) { offset++; } for (int i = tokens.Length; --i >= 0;) { if (StringUtil.RegionMatches(str0, true, offset, tokens[i], 0, tokens[i].Length)) { token = i; break; } } if (token == -1) { return(-1); } offset += tokens[token].Length; while (offset < length && Char.IsWhiteSpace(str0[offset])) { offset++; } char ch; if (offset < length && ((ch = str0[offset]) == '}' || (!last && ch == ','))) { position.SetIndex(offset + 1); return(token); } return(-1); }
/// <summary> /// Changes this MessageFormat to use the specified pattern. /// </summary> /// /// <param name="template">the pattern</param> /// <exception cref="IllegalArgumentException">when the pattern cannot be parsed</exception> public void ApplyPattern(String template) { int length = template.Length; StringBuilder buffer = new StringBuilder(); ParsePosition position = new ParsePosition(0); List <String> localStrings = new List <String>(); int argCount = 0; int[] args = new int[10]; int maxArg = -1; List <Format> localFormats = new List <Format>(); while (position.GetIndex() < length) { if (ILOG.J2CsMapping.Formatting.Format.UpTo(template, position, buffer, '{')) { int arg = 0; int offset = position.GetIndex(); if (offset >= length) { // text.19=Invalid argument number throw new ArgumentException("text.19"); //$NON-NLS-1$ } // Get argument number char ch; while ((ch = template[offset++]) != '}' && ch != ',') { if (ch < '0' && ch > '9') { // text.19=Invalid argument number throw new ArgumentException("text.19"); //$NON-NLS-1$ } arg = arg * 10 + (ch - '0'); if (arg < 0 || offset >= length) { // text.19=Invalid argument number throw new ArgumentException("text.19"); //$NON-NLS-1$ } } offset--; position.SetIndex(offset); localFormats.Add(ParseVariable(template, position)); if (argCount >= args.Length) { int[] newArgs = new int[args.Length * 2]; System.Array.Copy((Array)(args), 0, (Array)(newArgs), 0, args.Length); args = newArgs; } args[argCount++] = arg; if (arg > maxArg) { maxArg = arg; } } localStrings.Add(buffer.ToString()); buffer.Length = 0; } this.strings = new String[localStrings.Count]; for (int i = 0; i < localStrings.Count; i++) { this.strings[i] = localStrings[i]; } argumentNumbers = args; this.formats = new Format[argCount]; for (int i_0 = 0; i_0 < argCount; i_0++) { this.formats[i_0] = localFormats[i_0]; } maxOffset = argCount - 1; maxArgumentIndex = maxArg; }
private Format ParseVariable(String str0, ParsePosition position) { int length = str0.Length, offset = position.GetIndex(); char ch; if (offset >= length || ((ch = str0[offset++]) != '}' && ch != ',')) { // text.15=Missing element format throw new ArgumentException("text.15"); //$NON-NLS-1$ } position.SetIndex(offset); if (ch == '}') { return(null); } int type = Match(str0, position, false, new String[] { "time", //$NON-NLS-1$ "date", "number", "choice" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (type == -1) { // text.16=Unknown element format throw new ArgumentException("text.16"); //$NON-NLS-1$ } StringBuilder buffer = new StringBuilder(); ch = str0[position.GetIndex() - 1]; switch (type) { case 0: // time case 1: // date if (ch == '}') { return((type == 1) ? DateFormat.GetDateInstance( DateFormat.DEFAULT, locale) : DateFormat .GetTimeInstance(DateFormat.DEFAULT, locale)); } int dateStyle = Match(str0, position, true, new String[] { "full", "long", "medium", "short" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ if (dateStyle == -1) { ILOG.J2CsMapping.Formatting.Format.UpToWithQuotes(str0, position, buffer, '}', '{'); return(new SimpleDateFormat(buffer.ToString(), locale)); } switch (dateStyle) { case 0: dateStyle = DateFormat.FULL; break; case 1: dateStyle = DateFormat.LONG; break; case 2: dateStyle = DateFormat.MEDIUM; break; case 3: dateStyle = DateFormat.SHORT; break; } return((type == 1) ? DateFormat.GetDateInstance(dateStyle, locale) : DateFormat.GetTimeInstance(dateStyle, locale)); case 2: // number if (ch == '}') { return(NumberFormat.GetInstance()); } int numberStyle = Match(str0, position, true, new String[] { "currency", "percent", "integer" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (numberStyle == -1) { ILOG.J2CsMapping.Formatting.Format.UpToWithQuotes(str0, position, buffer, '}', '{'); return(new DecimalFormat(buffer.ToString(), new DecimalFormatSymbols(locale))); } switch (numberStyle) { case 0: // currency return(NumberFormat.GetCurrencyInstance(locale)); case 1: // percent return(NumberFormat.GetPercentInstance(locale)); } return(NumberFormat.GetIntegerInstance(locale)); } // choice try { ILOG.J2CsMapping.Formatting.Format.UpToWithQuotes(str0, position, buffer, '}', '{'); } catch (ArgumentException e) { // ignored } return(new ChoiceFormat(buffer.ToString())); }
/// <summary> /// Parse the message argument from the specified String starting at the /// index specified by the ParsePosition. If the string is successfully /// parsed, the index of the ParsePosition is updated to the index following /// the parsed text. /// </summary> /// /// <param name="string">the String to parse</param> /// <param name="position">the ParsePosition, updated on return with the index followingthe parsed text, or on error the index is unchanged and theerror index is set to the index where the error occurred</param> /// <returns>the array of Object arguments resulting from the parse, or null /// if there is an error</returns> public Object[] Parse(String str0, ParsePosition position) { if (str0 == null) { return(new Object[0]); } ParsePosition internalPos = new ParsePosition(0); int offset = position.GetIndex(); Object[] result = new Object[maxArgumentIndex + 1]; for (int i = 0; i <= maxOffset; i++) { String sub = strings[i]; if (!ILOG.J2CsMapping.Util.StringUtil.StartsWith(str0, sub, offset)) { position.SetErrorIndex(offset); return(null); } offset += sub.Length; Object parse; Format format = formats[i]; if (format == null) { if (i + 1 < strings.Length) { int next = ILOG.J2CsMapping.Util.StringUtil.IndexOf(str0, strings[i + 1], offset); if (next == -1) { position.SetErrorIndex(offset); return(null); } parse = str0.Substring(offset, (next) - (offset)); offset = next; } else { parse = str0.Substring(offset); offset = str0.Length; } } else { internalPos.SetIndex(offset); parse = format.ParseObject(str0, internalPos); if (internalPos.GetErrorIndex() != -1) { position.SetErrorIndex(offset); return(null); } offset = internalPos.GetIndex(); } result[argumentNumbers[i]] = parse; } if (maxOffset + 1 < strings.Length) { String sub_0 = strings[maxOffset + 1]; if (!ILOG.J2CsMapping.Util.StringUtil.StartsWith(str0, sub_0, offset)) { position.SetErrorIndex(offset); return(null); } offset += sub_0.Length; } position.SetIndex(offset); return(result); }
/// <summary> /// Parses the pattern to determine new strings and ranges for this /// ChoiceFormat. /// </summary> /// /// <param name="template">the pattern of strings and ranges</param> /// <exception cref="IllegalArgumentException">then an error occurs parsing the pattern</exception> public void ApplyPattern(String template) { double[] limits = new double[5]; IList <String> formats = new List <String>(); int length = template.Length, limitCount = 0, index = 0; StringBuilder buffer = new StringBuilder(); IBM.ICU.Text.NumberFormat format = IBM.ICU.Text.NumberFormat.GetInstance(ILOG.J2CsMapping.Util.Locale.US); ParsePosition position = new ParsePosition(0); while (true) { index = SkipWhitespace(template, index); if (index >= length) { if (limitCount == limits.Length) { choiceLimits = limits; } else { choiceLimits = new double[limitCount]; System.Array.Copy((Array)(limits), 0, (Array)(choiceLimits), 0, limitCount); } choiceFormats = new String[formats.Count]; for (int i = 0; i < formats.Count; i++) { choiceFormats[i] = formats[i]; } return; } position.SetIndex(index); object value_ren = format.Parse(template, position); index = SkipWhitespace(template, position.GetIndex()); if (position.GetErrorIndex() != -1 || index >= length) { // Fix Harmony 540 choiceLimits = new double[0]; choiceFormats = new String[0]; return; } char ch = template[index++]; if (limitCount == limits.Length) { double[] newLimits = new double[limitCount * 2]; System.Array.Copy((Array)(limits), 0, (Array)(newLimits), 0, limitCount); limits = newLimits; } double next; switch ((int)ch) { case '#': case '\u2264': next = Convert.ToDouble(value_ren); break; case '<': next = NextDouble(Convert.ToDouble(value_ren)); break; default: throw new ArgumentException(); } if (limitCount > 0 && next <= limits[limitCount - 1]) { throw new ArgumentException(); } buffer.Length = 0; position.SetIndex(index); ILOG.J2CsMapping.Formatting.Format.UpTo(template, position, buffer, '|'); index = position.GetIndex(); limits[limitCount++] = next; ILOG.J2CsMapping.Collections.Generics.Collections.Add(formats, buffer.ToString()); } }
// ----------------------------------------------------------------------- // parsing // ----------------------------------------------------------------------- /// <summary> /// Parses a string. Matches the string to be parsed against each of its /// rules (with a base value less than upperBound) and returns the value /// produced by the rule that matched the most charcters in the source /// string. /// </summary> /// /// <param name="text">The string to parse</param> /// <param name="parsePosition">The initial position is ignored and assumed to be 0. On exit,this object has been updated to point to the first characterposition this rule set didn't consume.</param> /// <param name="upperBound">Limits the rules that can be allowed to match. Only ruleswhose base values are strictly less than upperBound areconsidered.</param> /// <returns>The numerical result of parsing this string. This will be the /// matching rule's base value, composed appropriately with the /// results of matching any of its substitutions. The object will be /// an instance of Long if it's an integral value; otherwise, it will /// be an instance of Double. This function always returns a valid /// object: If nothing matched the input string at all, this function /// returns new Long(0), and the parse position is left unchanged.</returns> public object Parse(String text, ParsePosition parsePosition, double upperBound) { // try matching each rule in the rule set against the text being // parsed. Whichever one matches the most characters is the one // that determines the value we return. ParsePosition highWaterMark = new ParsePosition(0); object result = (long)(0); object tempResult = null; // dump out if there's no text to parse if (text.Length == 0) { return(result); } // start by trying the nehative number rule (if there is one) if (negativeNumberRule != null) { tempResult = negativeNumberRule.DoParse(text, parsePosition, false, upperBound); if (parsePosition.GetIndex() > highWaterMark.GetIndex()) { result = tempResult; highWaterMark.SetIndex(parsePosition.GetIndex()); } // commented out because the error-index API on ParsePosition isn't // there in 1.1.x // if (parsePosition.getErrorIndex() > // highWaterMark.getErrorIndex()) { // highWaterMark.setErrorIndex(parsePosition.getErrorIndex()); // } parsePosition.SetIndex(0); } // then try each of the fraction rules for (int i = 0; i < 3; i++) { if (fractionRules[i] != null) { tempResult = fractionRules[i].DoParse(text, parsePosition, false, upperBound); if (parsePosition.GetIndex() > highWaterMark.GetIndex()) { result = tempResult; highWaterMark.SetIndex(parsePosition.GetIndex()); } // commented out because the error-index API on ParsePosition // isn't there in 1.1.x // if (parsePosition.getErrorIndex() > // highWaterMark.getErrorIndex()) { // highWaterMark.setErrorIndex(parsePosition.getErrorIndex()); // } parsePosition.SetIndex(0); } } // finally, go through the regular rules one at a time. We start // at the end of the list because we want to try matching the most // sigificant rule first (this helps ensure that we parse // "five thousand three hundred six" as // "(five thousand) (three hundred) (six)" rather than // "((five thousand three) hundred) (six)"). Skip rules whose // base values are higher than the upper bound (again, this helps // limit ambiguity by making sure the rules that match a rule's // are less significant than the rule containing the substitutions)/ for (int i_0 = rules.Length - 1; i_0 >= 0 && highWaterMark.GetIndex() < text.Length; i_0--) { if (!isFractionRuleSet && rules[i_0].GetBaseValue() >= upperBound) { continue; } tempResult = rules[i_0].DoParse(text, parsePosition, isFractionRuleSet, upperBound); if (parsePosition.GetIndex() > highWaterMark.GetIndex()) { result = tempResult; highWaterMark.SetIndex(parsePosition.GetIndex()); } // commented out because the error-index API on ParsePosition isn't // there in 1.1.x // if (parsePosition.getErrorIndex() > // highWaterMark.getErrorIndex()) { // highWaterMark.setErrorIndex(parsePosition.getErrorIndex()); // } parsePosition.SetIndex(0); } // finally, update the parse postion we were passed to point to the // first character we didn't use, and return the result that // cporresponds to that string of characters parsePosition.SetIndex(highWaterMark.GetIndex()); // commented out because the error-index API on ParsePosition isn't // there in 1.1.x // if (parsePosition.getIndex() == 0) { // parsePosition.setErrorIndex(highWaterMark.getErrorIndex()); // } return(result); }