001: /*
002: * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * (C) Copyright IBM Corp. 2003 - All Rights Reserved
028: *
029: * The original version of this source code and documentation is
030: * copyrighted and owned by IBM. These materials are provided
031: * under terms of a License Agreement between IBM and Sun.
032: * This technology is protected by multiple US and International
033: * patents. This notice and attribution to IBM may not be removed.
034: */
035:
036: package sun.text;
037:
038: import java.text.CharacterIterator;
039:
040: public abstract class CodePointIterator {
041: public static final int DONE = -1;
042:
043: public abstract void setToStart();
044:
045: public abstract void setToLimit();
046:
047: public abstract int next();
048:
049: public abstract int prev();
050:
051: public abstract int charIndex();
052:
053: public static CodePointIterator create(char[] text) {
054: return new CharArrayCodePointIterator(text);
055: }
056:
057: public static CodePointIterator create(char[] text, int start,
058: int limit) {
059: return new CharArrayCodePointIterator(text, start, limit);
060: }
061:
062: public static CodePointIterator create(CharSequence text) {
063: return new CharSequenceCodePointIterator(text);
064: }
065:
066: public static CodePointIterator create(CharacterIterator iter) {
067: return new CharacterIteratorCodePointIterator(iter);
068: }
069: }
070:
071: final class CharArrayCodePointIterator extends CodePointIterator {
072: private char[] text;
073: private int start;
074: private int limit;
075: private int index;
076:
077: public CharArrayCodePointIterator(char[] text) {
078: this .text = text;
079: this .limit = text.length;
080: }
081:
082: public CharArrayCodePointIterator(char[] text, int start, int limit) {
083: if (start < 0 || limit < start || limit > text.length) {
084: throw new IllegalArgumentException();
085: }
086:
087: this .text = text;
088: this .start = this .index = start;
089: this .limit = limit;
090: }
091:
092: public void setToStart() {
093: index = start;
094: }
095:
096: public void setToLimit() {
097: index = limit;
098: }
099:
100: public int next() {
101: if (index < limit) {
102: char cp1 = text[index++];
103: if (Character.isHighSurrogate(cp1) && index < limit) {
104: char cp2 = text[index];
105: if (Character.isLowSurrogate(cp2)) {
106: ++index;
107: return Character.toCodePoint(cp1, cp2);
108: }
109: }
110: return cp1;
111: }
112: return DONE;
113: }
114:
115: public int prev() {
116: if (index > start) {
117: char cp2 = text[--index];
118: if (Character.isLowSurrogate(cp2) && index > start) {
119: char cp1 = text[index - 1];
120: if (Character.isHighSurrogate(cp1)) {
121: --index;
122: return Character.toCodePoint(cp1, cp2);
123: }
124: }
125: return cp2;
126: }
127: return DONE;
128: }
129:
130: public int charIndex() {
131: return index;
132: }
133: }
134:
135: final class CharSequenceCodePointIterator extends CodePointIterator {
136: private CharSequence text;
137: private int index;
138:
139: public CharSequenceCodePointIterator(CharSequence text) {
140: this .text = text;
141: }
142:
143: public void setToStart() {
144: index = 0;
145: }
146:
147: public void setToLimit() {
148: index = text.length();
149: }
150:
151: public int next() {
152: if (index < text.length()) {
153: char cp1 = text.charAt(index++);
154: if (Character.isHighSurrogate(cp1) && index < text.length()) {
155: char cp2 = text.charAt(index + 1);
156: if (Character.isLowSurrogate(cp2)) {
157: ++index;
158: return Character.toCodePoint(cp1, cp2);
159: }
160: }
161: return cp1;
162: }
163: return DONE;
164: }
165:
166: public int prev() {
167: if (index > 0) {
168: char cp2 = text.charAt(--index);
169: if (Character.isLowSurrogate(cp2) && index > 0) {
170: char cp1 = text.charAt(index - 1);
171: if (Character.isHighSurrogate(cp1)) {
172: --index;
173: return Character.toCodePoint(cp1, cp2);
174: }
175: }
176: return cp2;
177: }
178: return DONE;
179: }
180:
181: public int charIndex() {
182: return index;
183: }
184: }
185:
186: // note this has different iteration semantics than CharacterIterator
187: final class CharacterIteratorCodePointIterator extends
188: CodePointIterator {
189: private CharacterIterator iter;
190:
191: public CharacterIteratorCodePointIterator(CharacterIterator iter) {
192: this .iter = iter;
193: }
194:
195: public void setToStart() {
196: iter.setIndex(iter.getBeginIndex());
197: }
198:
199: public void setToLimit() {
200: iter.setIndex(iter.getEndIndex());
201: }
202:
203: public int next() {
204: char cp1 = iter.current();
205: if (cp1 != CharacterIterator.DONE) {
206: char cp2 = iter.next();
207: if (Character.isHighSurrogate(cp1)
208: && cp2 != CharacterIterator.DONE) {
209: if (Character.isLowSurrogate(cp2)) {
210: iter.next();
211: return Character.toCodePoint(cp1, cp2);
212: }
213: }
214: return cp1;
215: }
216: return DONE;
217: }
218:
219: public int prev() {
220: char cp2 = iter.previous();
221: if (cp2 != CharacterIterator.DONE) {
222: if (Character.isLowSurrogate(cp2)) {
223: char cp1 = iter.previous();
224: if (Character.isHighSurrogate(cp1)) {
225: return Character.toCodePoint(cp1, cp2);
226: }
227: iter.next();
228: }
229: return cp2;
230: }
231: return DONE;
232: }
233:
234: public int charIndex() {
235: return iter.getIndex();
236: }
237: }
|