]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/text/UCharacterIterator.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / text / UCharacterIterator.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.text;\r
8 \r
9 \r
10 import java.text.CharacterIterator;\r
11 \r
12 import com.ibm.icu.impl.CharacterIteratorWrapper;\r
13 import com.ibm.icu.impl.ReplaceableUCharacterIterator;\r
14 import com.ibm.icu.impl.UCharArrayIterator;\r
15 import com.ibm.icu.impl.UCharacterIteratorWrapper;\r
16 import com.ibm.icu.impl.UCharacterProperty;\r
17 \r
18 \r
19 /**\r
20  * Abstract class that defines an API for iteration on text objects.This is an \r
21  * interface for forward and backward iteration and random access into a text \r
22  * object. Forward iteration is done with post-increment and backward iteration \r
23  * is done with pre-decrement semantics, while the \r
24  * <code>java.text.CharacterIterator</code> interface methods provided forward \r
25  * iteration with "pre-increment" and backward iteration with pre-decrement \r
26  * semantics. This API is more efficient for forward iteration over code points.\r
27  * The other major difference is that this API can do both code unit and code point \r
28  * iteration, <code>java.text.CharacterIterator</code> can only iterate over \r
29  * code units and is limited to BMP (0 - 0xFFFF)\r
30  * @author Ram\r
31  * @stable ICU 2.4\r
32  */\r
33 public abstract class UCharacterIterator \r
34                       implements Cloneable,UForwardCharacterIterator {\r
35 \r
36     /**\r
37      * Protected default constructor for the subclasses\r
38      * @stable ICU 2.4\r
39      */\r
40     protected UCharacterIterator(){\r
41     }\r
42     \r
43     // static final methods ----------------------------------------------------\r
44     \r
45     /**\r
46      * Returns a <code>UCharacterIterator</code> object given a \r
47      * <code>Replaceable</code> object.\r
48      * @param source a valid source as a <code>Replaceable</code> object\r
49      * @return UCharacterIterator object\r
50      * @exception IllegalArgumentException if the argument is null\r
51      * @stable ICU 2.4\r
52      */\r
53     public static final UCharacterIterator getInstance(Replaceable source){\r
54         return new ReplaceableUCharacterIterator(source);\r
55     }\r
56     \r
57     /**\r
58      * Returns a <code>UCharacterIterator</code> object given a \r
59      * source string.\r
60      * @param source a string\r
61      * @return UCharacterIterator object\r
62      * @exception IllegalArgumentException if the argument is null\r
63      * @stable ICU 2.4\r
64      */\r
65     public static final UCharacterIterator getInstance(String source){\r
66         return new ReplaceableUCharacterIterator(source);\r
67     }\r
68     \r
69     /**\r
70      * Returns a <code>UCharacterIterator</code> object given a \r
71      * source character array.\r
72      * @param source an array of UTF-16 code units\r
73      * @return UCharacterIterator object\r
74      * @exception IllegalArgumentException if the argument is null\r
75      * @stable ICU 2.4\r
76      */\r
77     public static final UCharacterIterator getInstance(char[] source){\r
78         return getInstance(source,0,source.length);\r
79     }\r
80     \r
81     /**\r
82      * Returns a <code>UCharacterIterator</code> object given a \r
83      * source character array.\r
84      * @param source an array of UTF-16 code units\r
85      * @return UCharacterIterator object\r
86      * @exception IllegalArgumentException if the argument is null\r
87      * @stable ICU 2.4\r
88      */\r
89     public static final UCharacterIterator getInstance(char[] source, int start, int limit){\r
90         return new UCharArrayIterator(source,start,limit);\r
91     }\r
92     /**\r
93      * Returns a <code>UCharacterIterator</code> object given a \r
94      * source StringBuffer.\r
95      * @param source an string buffer of UTF-16 code units\r
96      * @return UCharacterIterator object\r
97      * @exception IllegalArgumentException if the argument is null\r
98      * @stable ICU 2.4\r
99      */\r
100     public static final UCharacterIterator getInstance(StringBuffer source){\r
101         return new ReplaceableUCharacterIterator(source);\r
102     }\r
103 \r
104     /**\r
105      * Returns a <code>UCharacterIterator</code> object given a \r
106      * CharacterIterator.\r
107      * @param source a valid CharacterIterator object.\r
108      * @return UCharacterIterator object\r
109      * @exception IllegalArgumentException if the argument is null\r
110      * @stable ICU 2.4\r
111      */    \r
112     public static final UCharacterIterator getInstance(CharacterIterator source){\r
113         return new CharacterIteratorWrapper(source);\r
114     }\r
115        \r
116     // public methods ----------------------------------------------------------\r
117     /**\r
118      * Returns a <code>java.text.CharacterIterator</code> object for\r
119      * the underlying text of this iterator.  The returned iterator is\r
120      * independent of this iterator.\r
121      * @return java.text.CharacterIterator object\r
122      * @stable ICU 2.4 \r
123      */\r
124     public CharacterIterator getCharacterIterator(){\r
125         return new UCharacterIteratorWrapper(this);\r
126     }    \r
127    \r
128     /**\r
129      * Returns the code unit at the current index.  If index is out\r
130      * of range, returns DONE.  Index is not changed.\r
131      * @return current code unit\r
132      * @stable ICU 2.4\r
133      */\r
134     public abstract int current();\r
135     \r
136     /**\r
137      * Returns the codepoint at the current index.\r
138      * If the current index is invalid, DONE is returned.\r
139      * If the current index points to a lead surrogate, and there is a following\r
140      * trail surrogate, then the code point is returned.  Otherwise, the code\r
141      * unit at index is returned.  Index is not changed. \r
142      * @return current codepoint\r
143      * @stable ICU 2.4\r
144      */\r
145     public int currentCodePoint(){\r
146         int ch = current();\r
147         if(UTF16.isLeadSurrogate((char)ch)){\r
148             // advance the index to get the\r
149             // next code point\r
150             next();\r
151             // due to post increment semantics\r
152             // current() after next() actually\r
153             // returns the char we want\r
154             int ch2 = current();\r
155             // current should never change\r
156             // the current index so back off\r
157             previous();\r
158             \r
159             if(UTF16.isTrailSurrogate((char)ch2)){\r
160                 // we found a surrogate pair \r
161                 // return the codepoint\r
162                 return UCharacterProperty.getRawSupplementary(\r
163                                                           (char)ch,(char)ch2\r
164                                                              );\r
165             }\r
166         }\r
167         return ch;\r
168     }\r
169     \r
170     /**\r
171      * Returns the length of the text\r
172      * @return length of the text\r
173      * @stable ICU 2.4\r
174      */\r
175     public abstract int getLength();\r
176 \r
177     \r
178     /**\r
179      * Gets the current index in text.\r
180      * @return current index in text.\r
181      * @stable ICU 2.4\r
182      */\r
183     public abstract int getIndex();\r
184 \r
185 \r
186     /**\r
187      * Returns the UTF16 code unit at index, and increments to the next\r
188      * code unit (post-increment semantics).  If index is out of\r
189      * range, DONE is returned, and the iterator is reset to the limit\r
190      * of the text.\r
191      * @return the next UTF16 code unit, or DONE if the index is at the limit\r
192      *         of the text.\r
193      * @stable ICU 2.4  \r
194      */\r
195     public abstract int next();\r
196 \r
197     /**\r
198      * Returns the code point at index, and increments to the next code\r
199      * point (post-increment semantics).  If index does not point to a\r
200      * valid surrogate pair, the behavior is the same as\r
201      * <code>next()<code>.  Otherwise the iterator is incremented past\r
202      * the surrogate pair, and the code point represented by the pair\r
203      * is returned.\r
204      * @return the next codepoint in text, or DONE if the index is at\r
205      *         the limit of the text.\r
206      * @stable ICU 2.4  \r
207      */\r
208     public int nextCodePoint(){\r
209         int ch1 = next();\r
210         if(UTF16.isLeadSurrogate((char)ch1)){\r
211             int ch2 = next();\r
212             if(UTF16.isTrailSurrogate((char)ch2)){\r
213                 return UCharacterProperty.getRawSupplementary((char)ch1,\r
214                                                               (char)ch2);\r
215             }else if (ch2 != DONE) {\r
216                 // unmatched surrogate so back out\r
217                 previous();\r
218             }\r
219         }\r
220         return ch1;\r
221     }\r
222 \r
223     /**\r
224      * Decrement to the position of the previous code unit in the\r
225      * text, and return it (pre-decrement semantics).  If the\r
226      * resulting index is less than 0, the index is reset to 0 and\r
227      * DONE is returned.\r
228      * @return the previous code unit in the text, or DONE if the new\r
229      *         index is before the start of the text.\r
230      * @stable ICU 2.4  \r
231      */\r
232     public abstract int previous();\r
233 \r
234     \r
235     /**\r
236      * Retreat to the start of the previous code point in the text,\r
237      * and return it (pre-decrement semantics).  If the index is not\r
238      * preceeded by a valid surrogate pair, the behavior is the same\r
239      * as <code>previous()</code>.  Otherwise the iterator is\r
240      * decremented to the start of the surrogate pair, and the code\r
241      * point represented by the pair is returned.\r
242      * @return the previous code point in the text, or DONE if the new\r
243      *         index is before the start of the text.\r
244      * @stable ICU 2.4  \r
245      */\r
246     public int previousCodePoint(){\r
247         int ch1 = previous();\r
248         if(UTF16.isTrailSurrogate((char)ch1)){\r
249             int ch2 = previous();\r
250             if(UTF16.isLeadSurrogate((char)ch2)){\r
251                 return UCharacterProperty.getRawSupplementary((char)ch2,\r
252                                                               (char)ch1);\r
253             }else if (ch2 != DONE) {\r
254                 //unmatched trail surrogate so back out\r
255                 next();\r
256             }   \r
257         }\r
258         return ch1;\r
259     }\r
260 \r
261     /**\r
262      * Sets the index to the specified index in the text.\r
263      * @param index the index within the text. \r
264      * @exception IndexOutOfBoundsException is thrown if an invalid index is \r
265      *            supplied\r
266      * @stable ICU 2.4\r
267      */\r
268     public abstract void setIndex(int index);\r
269 \r
270     /**\r
271      * Sets the current index to the limit.\r
272      * @stable ICU 2.4\r
273      */\r
274     public void setToLimit() {\r
275         setIndex(getLength());\r
276     }\r
277     \r
278     /**\r
279      * Sets the current index to the start.\r
280      * @stable ICU 2.4\r
281      */\r
282     public void setToStart() {\r
283         setIndex(0);\r
284     }\r
285 \r
286     /**\r
287      * Fills the buffer with the underlying text storage of the iterator\r
288      * If the buffer capacity is not enough a exception is thrown. The capacity\r
289      * of the fill in buffer should at least be equal to length of text in the \r
290      * iterator obtained by calling <code>getLength()</code).\r
291      * <b>Usage:</b>\r
292      * \r
293      * <code>\r
294      * <pre>\r
295      *         UChacterIterator iter = new UCharacterIterator.getInstance(text);\r
296      *         char[] buf = new char[iter.getLength()];\r
297      *         iter.getText(buf);\r
298      *         \r
299      *         OR\r
300      *         char[] buf= new char[1];\r
301      *         int len = 0;\r
302      *         for(;;){\r
303      *             try{\r
304      *                 len = iter.getText(buf);\r
305      *                 break;\r
306      *             }catch(IndexOutOfBoundsException e){\r
307      *                 buf = new char[iter.getLength()];\r
308      *             }\r
309      *         }\r
310      * </pre>\r
311      * </code>\r
312      *             \r
313      * @param fillIn an array of chars to fill with the underlying UTF-16 code \r
314      *         units.\r
315      * @param offset the position within the array to start putting the data.\r
316      * @return the number of code units added to fillIn, as a convenience\r
317      * @exception IndexOutOfBoundsException exception if there is not enough\r
318      *            room after offset in the array, or if offset < 0.\r
319      * @stable ICU 2.4  \r
320      */\r
321     public abstract int getText(char[] fillIn, int offset); \r
322 \r
323     /**\r
324      * Convenience override for <code>getText(char[], int)>/code> that provides\r
325      * an offset of 0.\r
326      * @param fillIn an array of chars to fill with the underlying UTF-16 code \r
327      *         units.\r
328      * @return the number of code units added to fillIn, as a convenience\r
329      * @exception IndexOutOfBoundsException exception if there is not enough\r
330      *            room in the array.\r
331      * @stable ICU 2.4  \r
332      */\r
333     public final int getText(char[] fillIn) {\r
334         return getText(fillIn, 0);\r
335     }\r
336          \r
337     /**\r
338      * Convenience method for returning the underlying text storage as as string\r
339      * @return the underlying text storage in the iterator as a string\r
340      * @stable ICU 2.4\r
341      */\r
342     public String getText() {\r
343         char[] text = new char[getLength()];\r
344         getText(text);\r
345         return new String(text);\r
346     }\r
347        \r
348     /**\r
349      * Moves the current position by the number of code units\r
350      * specified, either forward or backward depending on the sign\r
351      * of delta (positive or negative respectively).  If the resulting\r
352      * index would be less than zero, the index is set to zero, and if\r
353      * the resulting index would be greater than limit, the index is\r
354      * set to limit.\r
355      *\r
356      * @param delta the number of code units to move the current\r
357      *              index.\r
358      * @return the new index.\r
359      * @exception IndexOutOfBoundsException is thrown if an invalid index is \r
360      *            supplied \r
361      * @stable ICU 2.4 \r
362      * \r
363      */\r
364     public int moveIndex(int delta) {\r
365         int x = Math.max(0, Math.min(getIndex() + delta, getLength()));\r
366         setIndex(x);\r
367         return x;\r
368     }\r
369 \r
370     /**\r
371      * Moves the current position by the number of code points\r
372      * specified, either forward or backward depending on the sign of\r
373      * delta (positive or negative respectively). If the current index\r
374      * is at a trail surrogate then the first adjustment is by code\r
375      * unit, and the remaining adjustments are by code points.  If the\r
376      * resulting index would be less than zero, the index is set to\r
377      * zero, and if the resulting index would be greater than limit,\r
378      * the index is set to limit.\r
379      * @param delta the number of code units to move the current index.\r
380      * @return the new index  \r
381      * @exception IndexOutOfBoundsException is thrown if an invalid delta is \r
382      *            supplied\r
383      * @stable ICU 2.4\r
384      */\r
385     public int moveCodePointIndex(int delta){\r
386         if(delta>0){\r
387             while(delta>0 && nextCodePoint() != DONE){delta--;}\r
388         }else{\r
389             while(delta<0 && previousCodePoint() != DONE){delta++;}\r
390         }\r
391         if(delta!=0){\r
392             throw new IndexOutOfBoundsException();\r
393         }\r
394           \r
395         return getIndex();\r
396     }\r
397 \r
398     /**\r
399      * Creates a copy of this iterator, independent from other iterators.\r
400      * If it is not possible to clone the iterator, returns null.\r
401      * @return copy of this iterator\r
402      * @stable ICU 2.4\r
403      */\r
404     public Object clone() throws CloneNotSupportedException{\r
405         return super.clone();\r
406     }   \r
407     \r
408 }\r
409 \r