Home | History | Annotate | Download | only in number
      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