1 // 2017 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 package com.ibm.icu.impl.number; 4 5 import com.ibm.icu.impl.SimpleFormatterImpl; 6 import com.ibm.icu.text.NumberFormat.Field; 7 8 /** 9 * The second primary implementation of {@link Modifier}, this one consuming a {@link com.ibm.icu.text.SimpleFormatter} 10 * pattern. 11 */ 12 public class SimpleModifier implements Modifier { 13 private final String compiledPattern; 14 private final Field field; 15 private final boolean strong; 16 private final int prefixLength; 17 private final int suffixOffset; 18 private final int suffixLength; 19 20 /** TODO: This is copied from SimpleFormatterImpl. */ 21 private static final int ARG_NUM_LIMIT = 0x100; 22 23 /** Creates a modifier that uses the SimpleFormatter string formats. */ 24 public SimpleModifier(String compiledPattern, Field field, boolean strong) { 25 assert compiledPattern != null; 26 this.compiledPattern = compiledPattern; 27 this.field = field; 28 this.strong = strong; 29 30 assert SimpleFormatterImpl.getArgumentLimit(compiledPattern) == 1; 31 if (compiledPattern.charAt(1) != '\u0000') { 32 prefixLength = compiledPattern.charAt(1) - ARG_NUM_LIMIT; 33 suffixOffset = 3 + prefixLength; 34 } else { 35 prefixLength = 0; 36 suffixOffset = 2; 37 } 38 if (3 + prefixLength < compiledPattern.length()) { 39 suffixLength = compiledPattern.charAt(suffixOffset) - ARG_NUM_LIMIT; 40 } else { 41 suffixLength = 0; 42 } 43 } 44 45 @Override 46 public int apply(NumberStringBuilder output, int leftIndex, int rightIndex) { 47 return formatAsPrefixSuffix(output, leftIndex, rightIndex, field); 48 } 49 50 @Override 51 public int getPrefixLength() { 52 return prefixLength; 53 } 54 55 @Override 56 public int getCodePointCount() { 57 int count = 0; 58 if (prefixLength > 0) { 59 count += Character.codePointCount(compiledPattern, 2, 2 + prefixLength); 60 } 61 if (suffixLength > 0) { 62 count += Character.codePointCount(compiledPattern, 1 + suffixOffset, 1 + suffixOffset + suffixLength); 63 } 64 return count; 65 } 66 67 @Override 68 public boolean isStrong() { 69 return strong; 70 } 71 72 /** 73 * TODO: This belongs in SimpleFormatterImpl. The only reason I haven't moved it there yet is because 74 * DoubleSidedStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it. 75 * 76 * <p> 77 * Formats a value that is already stored inside the StringBuilder <code>result</code> between the indices 78 * <code>startIndex</code> and <code>endIndex</code> by inserting characters before the start index and after the 79 * end index. 80 * 81 * <p> 82 * This is well-defined only for patterns with exactly one argument. 83 * 84 * @param result 85 * The StringBuilder containing the value argument. 86 * @param startIndex 87 * The left index of the value within the string builder. 88 * @param endIndex 89 * The right index of the value within the string builder. 90 * @return The number of characters (UTF-16 code points) that were added to the StringBuilder. 91 */ 92 public int formatAsPrefixSuffix(NumberStringBuilder result, int startIndex, int endIndex, Field field) { 93 if (prefixLength > 0) { 94 result.insert(startIndex, compiledPattern, 2, 2 + prefixLength, field); 95 } 96 if (suffixLength > 0) { 97 result.insert(endIndex + prefixLength, compiledPattern, 1 + suffixOffset, 1 + suffixOffset + suffixLength, 98 field); 99 } 100 return prefixLength + suffixLength; 101 } 102 } 103