Home | History | Annotate | Download | only in text
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5 *******************************************************************************
      6 *
      7 *   Copyright (C) 2004-2010, International Business Machines
      8 *   Corporation and others.  All Rights Reserved.
      9 *
     10 *******************************************************************************
     11 *   file name:  ReplaceableContextIterator.java
     12 *   encoding:   US-ASCII
     13 *   tab size:   8 (not used)
     14 *   indentation:4
     15 *
     16 *   created on: 2005feb04
     17 *   created by: Markus W. Scherer
     18 *
     19 *   Implementation of UCaseProps.ContextIterator, iterates over a Replaceable.
     20 *   Java port of casetrn.cpp/utrans_rep_caseContextIterator().
     21 */
     22 
     23 package android.icu.text;
     24 
     25 import android.icu.impl.UCaseProps;
     26 
     27 /**
     28  * Implementation of UCaseProps.ContextIterator, iterates over a Replaceable.
     29  * See casetrn.cpp/utrans_rep_caseContextIterator().
     30  * See also UCharacter.StringContextIterator.
     31  */
     32 class ReplaceableContextIterator implements UCaseProps.ContextIterator {
     33     /**
     34      * Constructor.
     35      * @param rep Replaceable to iterate over.
     36      */
     37     ReplaceableContextIterator() {
     38         this.rep=null;
     39         limit=cpStart=cpLimit=index=contextStart=contextLimit=0;
     40         dir=0;
     41         reachedLimit=false;
     42     }
     43 
     44     /**
     45      * Set the text for iteration.
     46      * @param rep Iteration text.
     47      */
     48     public void setText(Replaceable rep) {
     49         this.rep=rep;
     50         limit=contextLimit=rep.length();
     51         cpStart=cpLimit=index=contextStart=0;
     52         dir=0;
     53         reachedLimit=false;
     54     }
     55 
     56     /**
     57      * Set the index where nextCaseMapCP() is to start iterating.
     58      * @param index Iteration start index for nextCaseMapCP().
     59      */
     60     public void setIndex(int index) {
     61         cpStart=cpLimit=index;
     62         this.index=0;
     63         dir=0;
     64         reachedLimit=false;
     65     }
     66 
     67     /**
     68      * Get the index of where the code point currently being case-mapped starts.
     69      * @return The start index of the current code point.
     70      */
     71     public int getCaseMapCPStart() {
     72         return cpStart;
     73     }
     74 
     75     /**
     76      * Set the iteration limit for nextCaseMapCP() to an index within the string.
     77      * If the limit parameter is negative or past the string, then the
     78      * string length is restored as the iteration limit.
     79      *
     80      * @param lim The iteration limit.
     81      */
     82     public void setLimit(int lim) {
     83         if(0<=lim && lim<=rep.length()) {
     84             limit=lim;
     85         } else {
     86             limit=rep.length();
     87         }
     88         reachedLimit=false;
     89     }
     90 
     91     /**
     92      * Set the start and limit indexes for context iteration with next().
     93      * @param contextStart Start of context for next().
     94      * @param contextLimit Limit of context for next().
     95      */
     96     public void setContextLimits(int contextStart, int contextLimit) {
     97         if(contextStart<0) {
     98             this.contextStart=0;
     99         } else if(contextStart<=rep.length()) {
    100             this.contextStart=contextStart;
    101         } else {
    102             this.contextStart=rep.length();
    103         }
    104         if(contextLimit<this.contextStart) {
    105             this.contextLimit=this.contextStart;
    106         } else if(contextLimit<=rep.length()) {
    107             this.contextLimit=contextLimit;
    108         } else {
    109             this.contextLimit=rep.length();
    110         }
    111         reachedLimit=false;
    112     }
    113 
    114     /**
    115      * Iterate forward through the string to fetch the next code point
    116      * to be case-mapped, and set the context indexes for it.
    117      *
    118      * @return The next code point to be case-mapped, or <0 when the iteration is done.
    119      */
    120     public int nextCaseMapCP() {
    121         int c;
    122         if(cpLimit<limit) {
    123             cpStart=cpLimit;
    124             c=rep.char32At(cpLimit);
    125             cpLimit+=UTF16.getCharCount(c);
    126             return c;
    127         } else {
    128             return -1;
    129         }
    130     }
    131 
    132     /**
    133      * Replace the current code point by its case mapping,
    134      * and update the indexes.
    135      *
    136      * @param text Replacement text.
    137      * @return The delta for the change of the text length.
    138      */
    139     public int replace(String text) {
    140         int delta=text.length()-(cpLimit-cpStart);
    141         rep.replace(cpStart, cpLimit, text);
    142         cpLimit+=delta;
    143         limit+=delta;
    144         contextLimit+=delta;
    145         return delta;
    146     }
    147 
    148     /**
    149      * Did forward context iteration with next() reach the iteration limit?
    150      * @return Boolean value.
    151      */
    152     public boolean didReachLimit() {
    153         return reachedLimit;
    154     }
    155 
    156     // implement UCaseProps.ContextIterator
    157     public void reset(int direction) {
    158         if(direction>0) {
    159             /* reset for forward iteration */
    160             this.dir=1;
    161             index=cpLimit;
    162         } else if(direction<0) {
    163             /* reset for backward iteration */
    164             this.dir=-1;
    165             index=cpStart;
    166         } else {
    167             // not a valid direction
    168             this.dir=0;
    169             index=0;
    170         }
    171         reachedLimit=false;
    172     }
    173 
    174     public int next() {
    175         int c;
    176 
    177         if(dir>0) {
    178             if(index<contextLimit) {
    179                 c=rep.char32At(index);
    180                 index+=UTF16.getCharCount(c);
    181                 return c;
    182             } else {
    183                 // forward context iteration reached the limit
    184                 reachedLimit=true;
    185             }
    186         } else if(dir<0 && index>contextStart) {
    187             c=rep.char32At(index-1);
    188             index-=UTF16.getCharCount(c);
    189             return c;
    190         }
    191         return -1;
    192     }
    193 
    194     // variables
    195     protected Replaceable rep;
    196     protected int index, limit, cpStart, cpLimit, contextStart, contextLimit;
    197     protected int dir; // 0=initial state  >0=forward  <0=backward
    198     protected boolean reachedLimit;
    199 }
    200