mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-10896 split SimplePatternFormatter into public SimpleFormatter and all-static SimpleFormatterImpl
X-SVN-Rev: 38194
This commit is contained in:
parent
b15fd37fa9
commit
00122edbf6
9 changed files with 308 additions and 239 deletions
|
@ -8,39 +8,21 @@ package com.ibm.icu.impl;
|
|||
|
||||
/**
|
||||
* Formats simple patterns like "{1} was born in {0}".
|
||||
* Minimal subset of MessageFormat; fast, simple, minimal dependencies.
|
||||
* Supports only numbered arguments with no type nor style parameters,
|
||||
* and formats only string values.
|
||||
* Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
|
||||
* Internal version of {@link com.ibm.icu.text.SimpleFormatter}
|
||||
* with only static methods, to avoid wrapper objects.
|
||||
*
|
||||
* <p>Factory methods throw exceptions for syntax errors
|
||||
* and for too few or too many arguments/placeholders.
|
||||
* <p>This class "compiles" pattern strings into a binary format
|
||||
* and implements formatting etc. based on that.
|
||||
*
|
||||
* <p>SimplePatternFormatter objects are immutable and can be safely cached like strings.
|
||||
* <p>Format:
|
||||
* Index 0: One more than the highest argument number.
|
||||
* Followed by zero or more arguments or literal-text segments.
|
||||
*
|
||||
* <p>Example:
|
||||
* <pre>
|
||||
* SimplePatternFormatter fmt = SimplePatternFormatter.compile("{1} '{born}' in {0}");
|
||||
*
|
||||
* // Output: "paul {born} in england"
|
||||
* System.out.println(fmt.format("england", "paul"));
|
||||
* </pre>
|
||||
*
|
||||
* @see com.ibm.icu.text.MessageFormat
|
||||
* @see com.ibm.icu.text.MessagePattern.ApostropheMode
|
||||
* <p>An argument is stored as its number, less than ARG_NUM_LIMIT.
|
||||
* A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
|
||||
* followed by that many chars.
|
||||
*/
|
||||
public final class SimplePatternFormatter {
|
||||
// For internal use in Java,
|
||||
// it is most efficient to compile patterns to compiled-pattern strings
|
||||
// and use them with static methods.
|
||||
//
|
||||
// If and when we make this public API,
|
||||
// we should probably make only the non-static methods public
|
||||
// and keep the static ones in an impl class.
|
||||
//
|
||||
// TODO: Consider changing methods & docs to use "argument" not "placeholder",
|
||||
// consistent with MessageFormat.
|
||||
|
||||
public final class SimpleFormatterImpl {
|
||||
/**
|
||||
* Argument numbers must be smaller than this limit.
|
||||
* Text segment lengths are offset by this much.
|
||||
|
@ -48,66 +30,53 @@ public final class SimplePatternFormatter {
|
|||
* except it is the maximum value of the first unit (max arg +1).
|
||||
*/
|
||||
private static final int ARG_NUM_LIMIT = 0x100;
|
||||
private static final char LEN1_CHAR = (char)(ARG_NUM_LIMIT + 1);
|
||||
private static final char LEN2_CHAR = (char)(ARG_NUM_LIMIT + 2);
|
||||
private static final char LEN3_CHAR = (char)(ARG_NUM_LIMIT + 3);
|
||||
/**
|
||||
* Initial and maximum char/UChar value set for a text segment.
|
||||
* Segment length char values are from ARG_NUM_LIMIT+1 to this value here.
|
||||
* Normally 0xffff, but can be as small as ARG_NUM_LIMIT+1 for testing.
|
||||
*/
|
||||
private static final char SEGMENT_LENGTH_PLACEHOLDER_CHAR = (char)0xffff;
|
||||
private static final char SEGMENT_LENGTH_ARGUMENT_CHAR = (char)0xffff;
|
||||
/**
|
||||
* Maximum length of a text segment. Longer segments are split into shorter ones.
|
||||
*/
|
||||
private static final int MAX_SEGMENT_LENGTH = SEGMENT_LENGTH_PLACEHOLDER_CHAR - ARG_NUM_LIMIT;
|
||||
private static final int MAX_SEGMENT_LENGTH = SEGMENT_LENGTH_ARGUMENT_CHAR - ARG_NUM_LIMIT;
|
||||
|
||||
/**
|
||||
* Binary representation of the compiled pattern.
|
||||
* Index 0: One more than the highest argument number.
|
||||
* Followed by zero or more arguments or literal-text segments.
|
||||
*
|
||||
* <p>An argument is stored as its number, less than ARG_NUM_LIMIT.
|
||||
* A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
|
||||
* followed by that many chars.
|
||||
*/
|
||||
private final String compiledPattern;
|
||||
/** "Intern" some common patterns. */
|
||||
private static final String[][] COMMON_PATTERNS = {
|
||||
{ "{0} {1}", "\u0002\u0000" + LEN1_CHAR + " \u0001" },
|
||||
{ "{0} ({1})", "\u0002\u0000" + LEN2_CHAR + " (\u0001" + LEN1_CHAR + ')' },
|
||||
{ "{0}, {1}", "\u0002\u0000" + LEN2_CHAR + ", \u0001" },
|
||||
{ "{0} – {1}", "\u0002\u0000" + LEN3_CHAR + " – \u0001" }, // en dash
|
||||
};
|
||||
|
||||
private SimplePatternFormatter(String compiledPattern) {
|
||||
this.compiledPattern = compiledPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatter from the pattern string.
|
||||
*
|
||||
* @param pattern The pattern string.
|
||||
* @return The new SimplePatternFormatter object.
|
||||
*/
|
||||
public static SimplePatternFormatter compile(CharSequence pattern) {
|
||||
return compileMinMaxPlaceholders(pattern, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatter from the pattern string.
|
||||
*
|
||||
* @param pattern The pattern string.
|
||||
* @param min The pattern must have at least this many placeholders.
|
||||
* @param max The pattern must have at most this many placeholders.
|
||||
* @return The new SimplePatternFormatter object.
|
||||
*/
|
||||
public static SimplePatternFormatter compileMinMaxPlaceholders(CharSequence pattern, int min, int max) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String compiledPattern = compileToStringMinMaxPlaceholders(pattern, sb, min, max);
|
||||
return new SimplePatternFormatter(compiledPattern);
|
||||
}
|
||||
/** Use only static methods. */
|
||||
private SimpleFormatterImpl() {}
|
||||
|
||||
/**
|
||||
* Creates a compiled form of the pattern string, for use with appropriate static methods.
|
||||
* The number of arguments checked against the given limits is the
|
||||
* highest argument number plus one, not the number of occurrences of arguments.
|
||||
*
|
||||
* @param pattern The pattern string.
|
||||
* @param min The pattern must have at least this many placeholders.
|
||||
* @param max The pattern must have at most this many placeholders.
|
||||
* @param min The pattern must have at least this many arguments.
|
||||
* @param max The pattern must have at most this many arguments.
|
||||
* @return The compiled-pattern string.
|
||||
* @throws IllegalArgumentException for bad argument syntax and too few or too many arguments.
|
||||
*/
|
||||
public static String compileToStringMinMaxPlaceholders(
|
||||
public static String compileToStringMinMaxArguments(
|
||||
CharSequence pattern, StringBuilder sb, int min, int max) {
|
||||
// Return some precompiled common two-argument patterns.
|
||||
if (min <= 2 && 2 <= max) {
|
||||
for (String[] pair : COMMON_PATTERNS) {
|
||||
if (pair[0].contentEquals(pattern)) {
|
||||
assert pair[1].charAt(0) == 2;
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parse consistent with MessagePattern, but
|
||||
// - support only simple numbered arguments
|
||||
// - build a simple binary structure into the result string
|
||||
|
@ -177,7 +146,7 @@ public final class SimplePatternFormatter {
|
|||
// Append c and track the literal-text segment length.
|
||||
if (textLength == 0) {
|
||||
// Reserve a char for the length of a new text segment, preset the maximum length.
|
||||
sb.append(SEGMENT_LENGTH_PLACEHOLDER_CHAR);
|
||||
sb.append(SEGMENT_LENGTH_ARGUMENT_CHAR);
|
||||
}
|
||||
sb.append(c);
|
||||
if (++textLength == MAX_SEGMENT_LENGTH) {
|
||||
|
@ -190,38 +159,24 @@ public final class SimplePatternFormatter {
|
|||
int argCount = maxArg + 1;
|
||||
if (argCount < min) {
|
||||
throw new IllegalArgumentException(
|
||||
"Fewer than minimum " + min + " placeholders in pattern \"" + pattern + "\"");
|
||||
"Fewer than minimum " + min + " arguments in pattern \"" + pattern + "\"");
|
||||
}
|
||||
if (argCount > max) {
|
||||
throw new IllegalArgumentException(
|
||||
"More than maximum " + max + " placeholders in pattern \"" + pattern + "\"");
|
||||
"More than maximum " + max + " arguments in pattern \"" + pattern + "\"");
|
||||
}
|
||||
sb.setCharAt(0, (char)argCount);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The max argument number/placeholder ID + 1.
|
||||
*/
|
||||
public int getPlaceholderCount() {
|
||||
return getPlaceholderCount(compiledPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param compiledPattern Compiled form of a pattern string.
|
||||
* @return The max argument number/placeholder ID + 1.
|
||||
* @return The max argument number + 1.
|
||||
*/
|
||||
public static int getPlaceholderCount(String compiledPattern) {
|
||||
public static int getArgumentLimit(String compiledPattern) {
|
||||
return compiledPattern.charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values.
|
||||
*/
|
||||
public String format(CharSequence... values) {
|
||||
return formatCompiledPattern(compiledPattern, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values.
|
||||
*
|
||||
|
@ -231,25 +186,6 @@ public final class SimplePatternFormatter {
|
|||
return formatAndAppend(compiledPattern, new StringBuilder(), null, values).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values, appending to the appendTo builder.
|
||||
*
|
||||
* @param appendTo Gets the formatted pattern and values appended.
|
||||
* @param 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 values The placeholder values.
|
||||
* A placeholder value must not be the same object as appendTo.
|
||||
* values.length must be at least getPlaceholderCount().
|
||||
* Can be null if getPlaceholderCount()==0.
|
||||
* @return appendTo
|
||||
*/
|
||||
public StringBuilder formatAndAppend(
|
||||
StringBuilder appendTo, int[] offsets, CharSequence... values) {
|
||||
return formatAndAppend(compiledPattern, appendTo, offsets, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values, appending to the appendTo builder.
|
||||
*
|
||||
|
@ -259,16 +195,16 @@ public final class SimplePatternFormatter {
|
|||
* 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 values The placeholder values.
|
||||
* A placeholder value must not be the same object as appendTo.
|
||||
* values.length must be at least getPlaceholderCount().
|
||||
* Can be null if getPlaceholderCount()==0.
|
||||
* @param values The argument values.
|
||||
* An argument value must not be the same object as appendTo.
|
||||
* values.length must be at least getArgumentLimit().
|
||||
* Can be null if getArgumentLimit()==0.
|
||||
* @return appendTo
|
||||
*/
|
||||
public static StringBuilder formatAndAppend(
|
||||
String compiledPattern, StringBuilder appendTo, int[] offsets, CharSequence... values) {
|
||||
int valuesLength = values != null ? values.length : 0;
|
||||
if (valuesLength < getPlaceholderCount(compiledPattern)) {
|
||||
if (valuesLength < getArgumentLimit(compiledPattern)) {
|
||||
throw new IllegalArgumentException("Too few values.");
|
||||
}
|
||||
return format(compiledPattern, values, appendTo, null, true, offsets);
|
||||
|
@ -277,27 +213,7 @@ public final class SimplePatternFormatter {
|
|||
/**
|
||||
* 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 initial argument's corresponding value.
|
||||
*
|
||||
* @param result Gets its contents replaced by the formatted pattern and values.
|
||||
* @param 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 values The placeholder values.
|
||||
* A placeholder value may be the same object as result.
|
||||
* values.length must be at least getPlaceholderCount().
|
||||
* @return result
|
||||
*/
|
||||
public StringBuilder formatAndReplace(
|
||||
StringBuilder result, int[] offsets, CharSequence... values) {
|
||||
return formatAndReplace(compiledPattern, result, offsets, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 initial argument's corresponding value.
|
||||
* as the value corresponding to the initial argument in the pattern.
|
||||
*
|
||||
* @param compiledPattern Compiled form of a pattern string.
|
||||
* @param result Gets its contents replaced by the formatted pattern and values.
|
||||
|
@ -305,15 +221,15 @@ public final class SimplePatternFormatter {
|
|||
* 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 values The placeholder values.
|
||||
* A placeholder value may be the same object as result.
|
||||
* values.length must be at least getPlaceholderCount().
|
||||
* @param values The argument values.
|
||||
* An argument value may be the same object as result.
|
||||
* values.length must be at least getArgumentLimit().
|
||||
* @return result
|
||||
*/
|
||||
public static StringBuilder formatAndReplace(
|
||||
String compiledPattern, StringBuilder result, int[] offsets, CharSequence... values) {
|
||||
int valuesLength = values != null ? values.length : 0;
|
||||
if (valuesLength < getPlaceholderCount(compiledPattern)) {
|
||||
if (valuesLength < getArgumentLimit(compiledPattern)) {
|
||||
throw new IllegalArgumentException("Too few values.");
|
||||
}
|
||||
|
||||
|
@ -324,7 +240,7 @@ public final class SimplePatternFormatter {
|
|||
// If any non-initial argument value is the same object as the result,
|
||||
// then we first copy its contents and use that instead while formatting.
|
||||
String resultCopy = null;
|
||||
if (getPlaceholderCount(compiledPattern) > 0) {
|
||||
if (getArgumentLimit(compiledPattern) > 0) {
|
||||
for (int i = 1; i < compiledPattern.length();) {
|
||||
int n = compiledPattern.charAt(i++);
|
||||
if (n < ARG_NUM_LIMIT) {
|
||||
|
@ -347,33 +263,13 @@ public final class SimplePatternFormatter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a string similar to the original pattern, only for debugging.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
String[] values = new String[getPlaceholderCount()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = String.format("{%d}", i);
|
||||
}
|
||||
return formatAndAppend(new StringBuilder(), null, values).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern text with none of the placeholders.
|
||||
* Like formatting with all-empty string values.
|
||||
*/
|
||||
public String getTextWithNoPlaceholders() {
|
||||
return getTextWithNoPlaceholders(compiledPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern text with none of the placeholders.
|
||||
* Returns the pattern text with none of the arguments.
|
||||
* Like formatting with all-empty string values.
|
||||
*
|
||||
* @param compiledPattern Compiled form of a pattern string.
|
||||
*/
|
||||
public static String getTextWithNoPlaceholders(String compiledPattern) {
|
||||
int capacity = compiledPattern.length() - 1 - getPlaceholderCount(compiledPattern);
|
||||
public static String getTextWithNoArguments(String compiledPattern) {
|
||||
int capacity = compiledPattern.length() - 1 - getArgumentLimit(compiledPattern);
|
||||
StringBuilder sb = new StringBuilder(capacity);
|
||||
for (int i = 1; i < compiledPattern.length();) {
|
||||
int segmentLength = compiledPattern.charAt(i++) - ARG_NUM_LIMIT;
|
|
@ -15,7 +15,7 @@ import java.util.Locale;
|
|||
import com.ibm.icu.impl.ICUCache;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.SimpleCache;
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
import com.ibm.icu.util.UResourceBundle;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import com.ibm.icu.util.UResourceBundle;
|
|||
* @stable ICU 50
|
||||
*/
|
||||
final public class ListFormatter {
|
||||
// Compiled SimplePatternFormatter patterns.
|
||||
// Compiled SimpleFormatter patterns.
|
||||
private final String two;
|
||||
private final String start;
|
||||
private final String middle;
|
||||
|
@ -124,7 +124,7 @@ final public class ListFormatter {
|
|||
}
|
||||
|
||||
private static String compilePattern(String pattern, StringBuilder sb) {
|
||||
return SimplePatternFormatter.compileToStringMinMaxPlaceholders(pattern, sb, 2, 2);
|
||||
return SimpleFormatterImpl.compileToStringMinMaxArguments(pattern, sb, 2, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +269,7 @@ final public class ListFormatter {
|
|||
// is true, records the offset of next in the formatted string.
|
||||
public FormattedListBuilder append(String pattern, Object next, boolean recordOffset) {
|
||||
int[] offsets = (recordOffset || offsetRecorded()) ? new int[2] : null;
|
||||
SimplePatternFormatter.formatAndReplace(
|
||||
SimpleFormatterImpl.formatAndReplace(
|
||||
pattern, current, offsets, current, next.toString());
|
||||
if (offsets != null) {
|
||||
if (offsets[0] == -1 || offsets[1] == -1) {
|
||||
|
|
|
@ -32,7 +32,7 @@ import com.ibm.icu.impl.DontCareFieldPosition;
|
|||
import com.ibm.icu.impl.ICUData;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.SimpleCache;
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
import com.ibm.icu.impl.StandardPlural;
|
||||
import com.ibm.icu.impl.UResource;
|
||||
import com.ibm.icu.math.BigDecimal;
|
||||
|
@ -427,7 +427,8 @@ public class MeasureFormat extends UFormat {
|
|||
StandardPlural.fromString(keywordHigh));
|
||||
|
||||
String rangeFormatter = getRangeFormat(getLocale(), formatWidth);
|
||||
String formattedNumber = SimplePatternFormatter.formatCompiledPattern(rangeFormatter, lowFormatted, highFormatted);
|
||||
String formattedNumber = SimpleFormatterImpl.formatCompiledPattern(
|
||||
rangeFormatter, lowFormatted, highFormatted);
|
||||
|
||||
if (isCurrency) {
|
||||
// Nasty hack
|
||||
|
@ -451,7 +452,7 @@ public class MeasureFormat extends UFormat {
|
|||
} else {
|
||||
String formatter =
|
||||
getPluralFormatter(lowValue.getUnit(), formatWidth, resolvedPlural.ordinal());
|
||||
return SimplePatternFormatter.formatCompiledPattern(formatter, formattedNumber);
|
||||
return SimpleFormatterImpl.formatCompiledPattern(formatter, formattedNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,7 +767,7 @@ public class MeasureFormat extends UFormat {
|
|||
}
|
||||
}
|
||||
if (patterns[index] == null) {
|
||||
patterns[index] = SimplePatternFormatter.compileToStringMinMaxPlaceholders(
|
||||
patterns[index] = SimpleFormatterImpl.compileToStringMinMaxArguments(
|
||||
value.getString(), sb, minPlaceholders, 1);
|
||||
}
|
||||
}
|
||||
|
@ -813,7 +814,7 @@ public class MeasureFormat extends UFormat {
|
|||
public void put(UResource.Key key, UResource.Value value) {
|
||||
if (key.contentEquals("per")) {
|
||||
cacheData.styleToPerPattern.put(width,
|
||||
SimplePatternFormatter.compileToStringMinMaxPlaceholders(
|
||||
SimpleFormatterImpl.compileToStringMinMaxArguments(
|
||||
value.getString(), sb, 2, 2));
|
||||
}
|
||||
}
|
||||
|
@ -996,13 +997,13 @@ public class MeasureFormat extends UFormat {
|
|||
String perUnitPattern =
|
||||
getFormatterOrNull(perUnit, formatWidth, MeasureFormatData.PER_UNIT_INDEX);
|
||||
if (perUnitPattern != null) {
|
||||
SimplePatternFormatter.formatAndAppend(perUnitPattern, appendTo, offsets, formatted);
|
||||
SimpleFormatterImpl.formatAndAppend(perUnitPattern, appendTo, offsets, formatted);
|
||||
return offsets[0];
|
||||
}
|
||||
String perPattern = getPerFormatter(formatWidth);
|
||||
String pattern = getPluralFormatter(perUnit, formatWidth, StandardPlural.ONE.ordinal());
|
||||
String perUnitString = SimplePatternFormatter.getTextWithNoPlaceholders(pattern).trim();
|
||||
SimplePatternFormatter.formatAndAppend(
|
||||
String perUnitString = SimpleFormatterImpl.getTextWithNoArguments(pattern).trim();
|
||||
SimpleFormatterImpl.formatAndAppend(
|
||||
perPattern, appendTo, offsets, formatted, perUnitString);
|
||||
return offsets[0];
|
||||
}
|
||||
|
@ -1414,7 +1415,7 @@ public class MeasureFormat extends UFormat {
|
|||
new ConcurrentHashMap<ULocale, String>();
|
||||
|
||||
/**
|
||||
* Return a formatter (compiled SimplePatternFormatter pattern) for a range, such as "{0}–{1}".
|
||||
* Return a formatter (compiled SimpleFormatter pattern) for a range, such as "{0}–{1}".
|
||||
* @param forLocale locale to get the format for
|
||||
* @param width the format width
|
||||
* @return range formatter, such as "{0}–{1}"
|
||||
|
@ -1449,7 +1450,8 @@ public class MeasureFormat extends UFormat {
|
|||
} catch ( MissingResourceException ex ) {
|
||||
resultString = rb.getStringWithFallback("NumberElements/latn/patterns/range");
|
||||
}
|
||||
result = SimplePatternFormatter.compileToStringMinMaxPlaceholders(resultString, new StringBuilder(), 2, 2);
|
||||
result = SimpleFormatterImpl.compileToStringMinMaxArguments(
|
||||
resultString, new StringBuilder(), 2, 2);
|
||||
localeIdToRangeFormat.put(forLocale, result);
|
||||
if (!forLocale.equals(realLocale)) {
|
||||
localeIdToRangeFormat.put(realLocale, result);
|
||||
|
|
|
@ -8,9 +8,10 @@ package com.ibm.icu.text;
|
|||
|
||||
import java.text.FieldPosition;
|
||||
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
import com.ibm.icu.impl.StandardPlural;
|
||||
import com.ibm.icu.text.PluralRules.FixedDecimal;
|
||||
import com.ibm.icu.text.SimpleFormatter;
|
||||
|
||||
/**
|
||||
* QuantityFormatter represents an unknown quantity of something and formats a known quantity
|
||||
|
@ -21,8 +22,8 @@ import com.ibm.icu.text.PluralRules.FixedDecimal;
|
|||
* PluralRules and DecimalFormat. It is package-protected as it is not meant for public use.
|
||||
*/
|
||||
class QuantityFormatter {
|
||||
private final SimplePatternFormatter[] templates =
|
||||
new SimplePatternFormatter[StandardPlural.COUNT];
|
||||
private final SimpleFormatter[] templates =
|
||||
new SimpleFormatter[StandardPlural.COUNT];
|
||||
|
||||
public QuantityFormatter() {}
|
||||
|
||||
|
@ -41,7 +42,7 @@ class QuantityFormatter {
|
|||
if (templates[idx] != null) {
|
||||
return;
|
||||
}
|
||||
templates[idx] = SimplePatternFormatter.compileMinMaxPlaceholders(template, 0, 1);
|
||||
templates[idx] = SimpleFormatter.compileMinMaxArguments(template, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +63,7 @@ class QuantityFormatter {
|
|||
public String format(double number, NumberFormat numberFormat, PluralRules pluralRules) {
|
||||
String formatStr = numberFormat.format(number);
|
||||
StandardPlural p = selectPlural(number, numberFormat, pluralRules);
|
||||
SimplePatternFormatter formatter = templates[p.ordinal()];
|
||||
SimpleFormatter formatter = templates[p.ordinal()];
|
||||
if (formatter == null) {
|
||||
formatter = templates[StandardPlural.OTHER_INDEX];
|
||||
assert formatter != null;
|
||||
|
@ -71,20 +72,20 @@ class QuantityFormatter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the SimplePatternFormatter for a particular variant.
|
||||
* Gets the SimpleFormatter for a particular variant.
|
||||
* @param variant "zero", "one", "two", "few", "many", "other"
|
||||
* @return the SimplePatternFormatter
|
||||
* @return the SimpleFormatter
|
||||
*/
|
||||
public SimplePatternFormatter getByVariant(CharSequence variant) {
|
||||
public SimpleFormatter getByVariant(CharSequence variant) {
|
||||
assert isValid();
|
||||
int idx = StandardPlural.indexOrOtherIndexFromString(variant);
|
||||
SimplePatternFormatter template = templates[idx];
|
||||
SimpleFormatter template = templates[idx];
|
||||
return (template == null && idx != StandardPlural.OTHER_INDEX) ?
|
||||
templates[StandardPlural.OTHER_INDEX] : template;
|
||||
}
|
||||
|
||||
// The following methods live here so that class PluralRules does not depend on number formatting,
|
||||
// and the SimplePatternFormatter does not depend on FieldPosition.
|
||||
// and the SimpleFormatter does not depend on FieldPosition.
|
||||
|
||||
/**
|
||||
* Selects the standard plural form for the number/formatter/rules.
|
||||
|
@ -123,7 +124,7 @@ class QuantityFormatter {
|
|||
public static StringBuilder format(String compiledPattern, CharSequence value,
|
||||
StringBuilder appendTo, FieldPosition pos) {
|
||||
int[] offsets = new int[1];
|
||||
SimplePatternFormatter.formatAndAppend(compiledPattern, appendTo, offsets, value);
|
||||
SimpleFormatterImpl.formatAndAppend(compiledPattern, appendTo, offsets, value);
|
||||
if (pos.getBeginIndex() != 0 || pos.getEndIndex() != 0) {
|
||||
if (offsets[0] >= 0) {
|
||||
pos.setBeginIndex(pos.getBeginIndex() + offsets[0]);
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.ibm.icu.impl.DontCareFieldPosition;
|
|||
import com.ibm.icu.impl.ICUCache;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.SimpleCache;
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
import com.ibm.icu.impl.StandardPlural;
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
|
@ -409,7 +409,7 @@ public final class RelativeDateTimeFormatter {
|
|||
numberFormat, pluralRules, formatStr, fieldPosition);
|
||||
|
||||
String formatter = getRelativeUnitPluralPattern(style, unit, pastFutureIndex, pluralForm);
|
||||
result = SimplePatternFormatter.formatCompiledPattern(formatter, formatStr);
|
||||
result = SimpleFormatterImpl.formatCompiledPattern(formatter, formatStr);
|
||||
}
|
||||
return adjustForContext(result);
|
||||
|
||||
|
@ -852,7 +852,7 @@ public final class RelativeDateTimeFormatter {
|
|||
@Override
|
||||
public void put(UResource.Key key, UResource.Value value) {
|
||||
/* Make two lists of simplePatternFmtList, one for past and one for future.
|
||||
* Set a SimplePatternFormatter for the <style, relative unit, plurality>
|
||||
* Set a SimpleFormatter pattern for the <style, relative unit, plurality>
|
||||
*
|
||||
* Fill in values for the particular plural given, e.g., ONE, FEW, OTHER, etc.
|
||||
*/
|
||||
|
@ -869,9 +869,9 @@ public final class RelativeDateTimeFormatter {
|
|||
}
|
||||
int pluralIndex = StandardPlural.indexFromString(key.toString());
|
||||
if (patterns[pastFutureIndex][pluralIndex] == null) {
|
||||
patterns[pastFutureIndex][pluralIndex] =
|
||||
SimplePatternFormatter.compileToStringMinMaxPlaceholders(value.getString(),
|
||||
sb, 0, 1);
|
||||
patterns[pastFutureIndex][pluralIndex] =
|
||||
SimpleFormatterImpl.compileToStringMinMaxArguments(
|
||||
value.getString(), sb, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014-2016, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.text;
|
||||
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
|
||||
/**
|
||||
* Formats simple patterns like "{1} was born in {0}".
|
||||
* Minimal subset of MessageFormat; fast, simple, minimal dependencies.
|
||||
* Supports only numbered arguments with no type nor style parameters,
|
||||
* and formats only string values.
|
||||
* Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
|
||||
*
|
||||
* <p>Factory methods throw exceptions for syntax errors
|
||||
* and for too few or too many arguments/placeholders.
|
||||
*
|
||||
* <p>SimpleFormatter objects are immutable and can be safely cached like strings.
|
||||
*
|
||||
* <p>Example:
|
||||
* <pre>
|
||||
* SimpleFormatter fmt = SimpleFormatter.compile("{1} '{born}' in {0}");
|
||||
*
|
||||
* // Output: "paul {born} in england"
|
||||
* System.out.println(fmt.format("england", "paul"));
|
||||
* </pre>
|
||||
*
|
||||
* @see MessageFormat
|
||||
* @see MessagePattern.ApostropheMode
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public final class SimpleFormatter {
|
||||
// For internal use in Java, use SimpleFormatterImpl directly instead:
|
||||
// It is most efficient to compile patterns to compiled-pattern strings
|
||||
// and use them with static methods.
|
||||
// (Avoids allocating SimpleFormatter wrapper objects.)
|
||||
|
||||
/**
|
||||
* Binary representation of the compiled pattern.
|
||||
* @see SimpleFormatterImpl
|
||||
*/
|
||||
private final String compiledPattern;
|
||||
|
||||
private SimpleFormatter(String compiledPattern) {
|
||||
this.compiledPattern = compiledPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatter from the pattern string.
|
||||
*
|
||||
* @param pattern The pattern string.
|
||||
* @return The new SimpleFormatter object.
|
||||
* @throws IllegalArgumentException for bad argument syntax.
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static SimpleFormatter compile(CharSequence pattern) {
|
||||
return compileMinMaxArguments(pattern, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param pattern The pattern string.
|
||||
* @param min The pattern must have at least this many arguments.
|
||||
* @param max The pattern must have at most this many arguments.
|
||||
* @return The new SimpleFormatter object.
|
||||
* @throws IllegalArgumentException for bad argument syntax and too few or too many arguments.
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static SimpleFormatter compileMinMaxArguments(CharSequence pattern, int min, int max) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String compiledPattern = SimpleFormatterImpl.compileToStringMinMaxArguments(pattern, sb, min, max);
|
||||
return new SimpleFormatter(compiledPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The max argument number + 1.
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public int getArgumentLimit() {
|
||||
return SimpleFormatterImpl.getArgumentLimit(compiledPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values.
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public String format(CharSequence... values) {
|
||||
return SimpleFormatterImpl.formatCompiledPattern(compiledPattern, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given values, appending to the appendTo builder.
|
||||
*
|
||||
* @param appendTo Gets the formatted pattern and values appended.
|
||||
* @param 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 values The argument values.
|
||||
* An argument value must not be the same object as appendTo.
|
||||
* values.length must be at least getArgumentLimit().
|
||||
* Can be null if getArgumentLimit()==0.
|
||||
* @return appendTo
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public StringBuilder formatAndAppend(
|
||||
StringBuilder appendTo, int[] offsets, CharSequence... values) {
|
||||
return SimpleFormatterImpl.formatAndAppend(compiledPattern, appendTo, offsets, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param result Gets its contents replaced by the formatted pattern and values.
|
||||
* @param 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 values The argument values.
|
||||
* An argument value may be the same object as result.
|
||||
* values.length must be at least getArgumentLimit().
|
||||
* @return result
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public StringBuilder formatAndReplace(
|
||||
StringBuilder result, int[] offsets, CharSequence... values) {
|
||||
return SimpleFormatterImpl.formatAndReplace(compiledPattern, result, offsets, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string similar to the original pattern, only for debugging.
|
||||
*
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
String[] values = new String[getArgumentLimit()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = "{" + i + '}';
|
||||
}
|
||||
return formatAndAppend(new StringBuilder(), null, values).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern text with none of the arguments.
|
||||
* Like formatting with all-empty string values.
|
||||
*
|
||||
* @draft ICU 57
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public String getTextWithNoArguments() {
|
||||
return SimpleFormatterImpl.getTextWithNoArguments(compiledPattern);
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ package com.ibm.icu.dev.test.format;
|
|||
import java.util.Arrays;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.SimpleFormatterImpl;
|
||||
import com.ibm.icu.impl.StandardPlural;
|
||||
import com.ibm.icu.text.MeasureFormat;
|
||||
import com.ibm.icu.text.MeasureFormat.FormatWidth;
|
||||
|
@ -62,7 +62,7 @@ public class PluralRangesTest extends TestFmwk {
|
|||
FormatWidth width = FormatWidth.valueOf(test[1]);
|
||||
String expected = test[2];
|
||||
String formatter = MeasureFormat.getRangeFormat(ulocale, width);
|
||||
String actual = SimplePatternFormatter.formatCompiledPattern(formatter, "{0}", "{1}");
|
||||
String actual = SimpleFormatterImpl.formatCompiledPattern(formatter, "{0}", "{1}");
|
||||
assertEquals("range pattern " + Arrays.asList(test), expected, actual);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
* Copyright (C) 1996-2016, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.impl;
|
||||
|
@ -22,7 +22,7 @@ public class TestAll extends TestGroup {
|
|||
"ICUServiceTest",
|
||||
"ICUServiceThreadTest",
|
||||
"ICUBinaryTest",
|
||||
"SimplePatternFormatterTest",
|
||||
"SimpleFormatterTest",
|
||||
"TextTrieMapTest"
|
||||
},
|
||||
"Test miscellaneous implementation utilities");
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
package com.ibm.icu.dev.test.util;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
import com.ibm.icu.text.SimpleFormatter;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
public class SimplePatternFormatterTest extends TestFmwk {
|
||||
public class SimpleFormatterTest extends TestFmwk {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SimplePatternFormatterTest()
|
||||
public SimpleFormatterTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -24,20 +24,20 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
|
||||
public static void main(String arg[])
|
||||
{
|
||||
SimplePatternFormatterTest test = new SimplePatternFormatterTest();
|
||||
SimpleFormatterTest test = new SimpleFormatterTest();
|
||||
try {
|
||||
test.run(arg);
|
||||
} catch (Exception e) {
|
||||
test.errln("Error testing SimplePatternFormatterTest");
|
||||
test.errln("Error testing SimpleFormatterTest");
|
||||
}
|
||||
}
|
||||
|
||||
public void TestWithNoPlaceholders() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("This doesn''t have templates '{0}");
|
||||
public void TestWithNoArguments() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("This doesn''t have templates '{0}");
|
||||
assertEquals(
|
||||
"getPlaceholderCount",
|
||||
"getArgumentLimit",
|
||||
0,
|
||||
fmt.getPlaceholderCount());
|
||||
fmt.getArgumentLimit());
|
||||
assertEquals(
|
||||
"format",
|
||||
"This doesn't have templates {0}",
|
||||
|
@ -71,41 +71,41 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
|
||||
public void TestSyntaxErrors() {
|
||||
try {
|
||||
SimplePatternFormatter.compile("{}");
|
||||
SimpleFormatter.compile("{}");
|
||||
fail("Syntax error did not yield an exception.");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
try {
|
||||
SimplePatternFormatter.compile("{12d");
|
||||
SimpleFormatter.compile("{12d");
|
||||
fail("Syntax error did not yield an exception.");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void TestOnePlaceholder() {
|
||||
assertEquals("TestOnePlaceholder",
|
||||
public void TestOneArgument() {
|
||||
assertEquals("TestOneArgument",
|
||||
"1 meter",
|
||||
SimplePatternFormatter.compile("{0} meter").format("1"));
|
||||
SimpleFormatter.compile("{0} meter").format("1"));
|
||||
}
|
||||
|
||||
public void TestBigPlaceholder() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("a{20}c");
|
||||
assertEquals("{20} count", 21, fmt.getPlaceholderCount());
|
||||
public void TestBigArgument() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("a{20}c");
|
||||
assertEquals("{20} count", 21, fmt.getArgumentLimit());
|
||||
CharSequence[] values = new CharSequence[21];
|
||||
values[20] = "b";
|
||||
assertEquals("{20}=b", "abc", fmt.format(values));
|
||||
}
|
||||
|
||||
public void TestGetTextWithNoPlaceholders() {
|
||||
public void TestGetTextWithNoArguments() {
|
||||
assertEquals(
|
||||
"",
|
||||
"Templates and are here.",
|
||||
SimplePatternFormatter.compile(
|
||||
"Templates {1}{2} and {3} are here.").getTextWithNoPlaceholders());
|
||||
SimpleFormatter.compile(
|
||||
"Templates {1}{2} and {3} are here.").getTextWithNoArguments());
|
||||
}
|
||||
|
||||
public void TestTooFewPlaceholderValues() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile(
|
||||
public void TestTooFewArgumentValues() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile(
|
||||
"Templates {2}{1} and {4} are out of order.");
|
||||
try {
|
||||
fmt.format("freddy", "tommy", "frog", "leg");
|
||||
|
@ -129,13 +129,13 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
}
|
||||
}
|
||||
|
||||
public void TestWithPlaceholders() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile(
|
||||
public void TestWithArguments() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile(
|
||||
"Templates {2}{1} and {4} are out of order.");
|
||||
assertEquals(
|
||||
"getPlaceholderCount",
|
||||
"getArgumentLimit",
|
||||
5,
|
||||
fmt.getPlaceholderCount());
|
||||
fmt.getArgumentLimit());
|
||||
assertEquals(
|
||||
"toString",
|
||||
"Templates {2}{1} and {4} are out of order.",
|
||||
|
@ -153,9 +153,9 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
verifyOffsets(expectedOffsets, offsets);
|
||||
}
|
||||
|
||||
public void TestFormatUseAppendToAsPlaceholder() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile(
|
||||
"Placeholders {0} and {1}");
|
||||
public void TestFormatUseAppendToAsArgument() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile(
|
||||
"Arguments {0} and {1}");
|
||||
StringBuilder appendTo = new StringBuilder("previous:");
|
||||
try {
|
||||
fmt.formatAndAppend(appendTo, null, appendTo, "frog");
|
||||
|
@ -166,7 +166,7 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
}
|
||||
|
||||
public void TestFormatReplaceNoOptimization() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
int[] offsets = new int[4];
|
||||
StringBuilder result = new StringBuilder("original");
|
||||
assertEquals(
|
||||
|
@ -183,7 +183,7 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
|
||||
|
||||
public void TestFormatReplaceNoOptimizationLeadingText() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("boo {2}, {0}, {1} and {3}");
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("boo {2}, {0}, {1} and {3}");
|
||||
int[] offsets = new int[4];
|
||||
StringBuilder result = new StringBuilder("original");
|
||||
assertEquals(
|
||||
|
@ -199,7 +199,7 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
}
|
||||
|
||||
public void TestFormatReplaceOptimization() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
int[] offsets = new int[4];
|
||||
StringBuilder result = new StringBuilder("original");
|
||||
assertEquals(
|
||||
|
@ -215,7 +215,7 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
}
|
||||
|
||||
public void TestFormatReplaceOptimizationNoOffsets() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}");
|
||||
StringBuilder result = new StringBuilder("original");
|
||||
assertEquals(
|
||||
"format",
|
||||
|
@ -228,17 +228,17 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
}
|
||||
|
||||
public void TestFormatReplaceNoOptimizationNoOffsets() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile(
|
||||
"Placeholders {0} and {1}");
|
||||
SimpleFormatter fmt = SimpleFormatter.compile(
|
||||
"Arguments {0} and {1}");
|
||||
StringBuilder result = new StringBuilder("previous:");
|
||||
assertEquals(
|
||||
"",
|
||||
"Placeholders previous: and frog",
|
||||
"Arguments previous: and frog",
|
||||
fmt.formatAndReplace(result, null, result, "frog").toString());
|
||||
}
|
||||
|
||||
public void TestFormatReplaceNoOptimizationLeadingPlaceholderUsedTwice() {
|
||||
SimplePatternFormatter fmt = SimplePatternFormatter.compile(
|
||||
public void TestFormatReplaceNoOptimizationLeadingArgumentUsedTwice() {
|
||||
SimpleFormatter fmt = SimpleFormatter.compile(
|
||||
"{2}, {0}, {1} and {3} {2}");
|
||||
StringBuilder result = new StringBuilder("original");
|
||||
int[] offsets = new int[4];
|
||||
|
@ -255,11 +255,11 @@ public class SimplePatternFormatterTest extends TestFmwk {
|
|||
|
||||
public void TestQuotingLikeMessageFormat() {
|
||||
String pattern = "{0} don't can''t '{5}''}{a' again '}'{1} to the '{end";
|
||||
SimplePatternFormatter spf = SimplePatternFormatter.compile(pattern);
|
||||
SimpleFormatter spf = SimpleFormatter.compile(pattern);
|
||||
MessageFormat mf = new MessageFormat(pattern, ULocale.ROOT);
|
||||
String expected = "X don't can't {5}'}{a again }Y to the {end";
|
||||
assertEquals("MessageFormat", expected, mf.format(new Object[] { "X", "Y" }));
|
||||
assertEquals("SimplePatternFormatter", expected, spf.format("X", "Y"));
|
||||
assertEquals("SimpleFormatter", expected, spf.format("X", "Y"));
|
||||
}
|
||||
|
||||
void verifyOffsets(int[] expected, int[] actual) {
|
Loading…
Add table
Reference in a new issue