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