001: /*
002: *******************************************************************************
003: * Copyright (C) 1996-2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.impl;
008:
009: import com.ibm.icu.text.UCharacterIterator;
010:
011: /**
012: * Used by Collation. UCharacterIterator on Strings. Can't use
013: * ReplaceableUCharacterIterator because it is not easy to do a fast setText.
014: * @author synwee
015: */
016: // TODO: Investivate if setText is a feature required by users so that we can
017: // move this method to the base class!
018: public final class StringUCharacterIterator extends UCharacterIterator {
019:
020: // public constructor ------------------------------------------------------
021:
022: /**
023: * Public constructor
024: * @param str text which the iterator will be based on
025: */
026: public StringUCharacterIterator(String str) {
027: if (str == null) {
028: throw new IllegalArgumentException();
029: }
030: m_text_ = str;
031: m_currentIndex_ = 0;
032: }
033:
034: /**
035: * Public default constructor
036: */
037: public StringUCharacterIterator() {
038: m_text_ = "";
039: m_currentIndex_ = 0;
040: }
041:
042: // public methods ----------------------------------------------------------
043:
044: /**
045: * Creates a copy of this iterator, does not clone the underlying
046: * <code>String</code>object
047: * @return copy of this iterator
048: */
049: ///CLOVER:OFF
050: public Object clone() {
051: try {
052: return super .clone();
053: } catch (CloneNotSupportedException e) {
054: return null; // never invoked
055: }
056: }
057:
058: ///CLOVER:ON
059: /**
060: * Returns the current UTF16 character.
061: * @return current UTF16 character
062: */
063: public int current() {
064: if (m_currentIndex_ < m_text_.length()) {
065: return m_text_.charAt(m_currentIndex_);
066: }
067: return DONE;
068: }
069:
070: /**
071: * Returns the length of the text
072: * @return length of the text
073: */
074: public int getLength() {
075: return m_text_.length();
076: }
077:
078: /**
079: * Gets the current currentIndex in text.
080: * @return current currentIndex in text.
081: */
082: public int getIndex() {
083: return m_currentIndex_;
084: }
085:
086: /**
087: * Returns next UTF16 character and increments the iterator's currentIndex
088: * by 1.
089: * If the resulting currentIndex is greater or equal to the text length,
090: * the currentIndex is reset to the text length and a value of DONE is
091: * returned.
092: * @return next UTF16 character in text or DONE if the new currentIndex is
093: * off the end of the text range.
094: */
095: public int next() {
096: if (m_currentIndex_ < m_text_.length()) {
097: return m_text_.charAt(m_currentIndex_++);
098: }
099: return DONE;
100: }
101:
102: /**
103: * Returns previous UTF16 character and decrements the iterator's
104: * currentIndex by 1.
105: * If the resulting currentIndex is less than 0, the currentIndex is reset
106: * to 0 and a value of DONE is returned.
107: * @return next UTF16 character in text or DONE if the new currentIndex is
108: * off the start of the text range.
109: */
110: public int previous() {
111: if (m_currentIndex_ > 0) {
112: return m_text_.charAt(--m_currentIndex_);
113: }
114: return DONE;
115: }
116:
117: /**
118: * <p>Sets the currentIndex to the specified currentIndex in the text and
119: * returns that single UTF16 character at currentIndex.
120: * This assumes the text is stored as 16-bit code units.</p>
121: * @param currentIndex the currentIndex within the text.
122: * @exception IndexOutOfBoundsException is thrown if an invalid currentIndex
123: * is supplied. i.e. currentIndex is out of bounds.
124: */
125: public void setIndex(int currentIndex)
126: throws IndexOutOfBoundsException {
127: if (currentIndex < 0 || currentIndex > m_text_.length()) {
128: throw new IndexOutOfBoundsException();
129: }
130: m_currentIndex_ = currentIndex;
131: }
132:
133: /**
134: * Fills the buffer with the underlying text storage of the iterator
135: * If the buffer capacity is not enough a exception is thrown. The capacity
136: * of the fill in buffer should at least be equal to length of text in the
137: * iterator obtained by calling <code>getLength()</code).
138: * <b>Usage:</b>
139: *
140: * <code>
141: * <pre>
142: * UChacterIterator iter = new UCharacterIterator.getInstance(text);
143: * char[] buf = new char[iter.getLength()];
144: * iter.getText(buf);
145: *
146: * OR
147: * char[] buf= new char[1];
148: * int len = 0;
149: * for(;;){
150: * try{
151: * len = iter.getText(buf);
152: * break;
153: * }catch(IndexOutOfBoundsException e){
154: * buf = new char[iter.getLength()];
155: * }
156: * }
157: * </pre>
158: * </code>
159: *
160: * @param fillIn an array of chars to fill with the underlying UTF-16 code
161: * units.
162: * @param offset the position within the array to start putting the data.
163: * @return the number of code units added to fillIn, as a convenience
164: * @exception IndexOutOfBoundsException exception if there is not enough
165: * room after offset in the array, or if offset < 0.
166: */
167: ///CLOVER:OFF
168: public int getText(char[] fillIn, int offset) {
169: int length = m_text_.length();
170: if (offset < 0 || offset + length > fillIn.length) {
171: throw new IndexOutOfBoundsException(Integer
172: .toString(length));
173: }
174: m_text_.getChars(0, length, fillIn, offset);
175: return length;
176: }
177:
178: ///CLOVER:ON
179: /**
180: * Convenience method for returning the underlying text storage as as
181: * string
182: * @return the underlying text storage in the iterator as a string
183: */
184: public String getText() {
185: return m_text_;
186: }
187:
188: /**
189: * Reset this iterator to point to a new string. This method is used by
190: * other classes that want to avoid allocating new
191: * ReplaceableCharacterIterator objects every time their setText method
192: * is called.
193: * @param text The String to be iterated over
194: */
195: public void setText(String text) {
196: if (text == null) {
197: throw new NullPointerException();
198: }
199: m_text_ = text;
200: m_currentIndex_ = 0;
201: }
202:
203: // private data members ----------------------------------------------------
204:
205: /**
206: * Text string object
207: */
208: private String m_text_;
209: /**
210: * Current currentIndex
211: */
212: private int m_currentIndex_;
213:
214: }
|