1 /* 2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * (C) Copyright IBM Corp. 2003 - All Rights Reserved 28 * 29 * The original version of this source code and documentation is 30 * copyrighted and owned by IBM. These materials are provided 31 * under terms of a License Agreement between IBM and Sun. 32 * This technology is protected by multiple US and International 33 * patents. This notice and attribution to IBM may not be removed. 34 */ 35 36 package sun.text; 37 38 import java.text.CharacterIterator; 39 40 public abstract class CodePointIterator { 41 public static final int DONE = -1; 42 43 public abstract void setToStart(); 44 public abstract void setToLimit(); 45 46 public abstract int next(); 47 public abstract int prev(); 48 49 public abstract int charIndex(); 50 51 public static CodePointIterator create(char[] text) { 52 return new CharArrayCodePointIterator(text); 53 } 54 55 public static CodePointIterator create(char[] text, int start, int limit) { 56 return new CharArrayCodePointIterator(text, start, limit); 57 } 58 59 public static CodePointIterator create(CharSequence text) { 60 return new CharSequenceCodePointIterator(text); 61 } 62 63 public static CodePointIterator create(CharacterIterator iter) { 64 return new CharacterIteratorCodePointIterator(iter); 65 } 66 } 67 68 final class CharArrayCodePointIterator extends CodePointIterator { 69 private char[] text; 70 private int start; 71 private int limit; 72 private int index; 73 74 public CharArrayCodePointIterator(char[] text) { 75 this.text = text; 76 this.limit = text.length; 77 } 78 79 public CharArrayCodePointIterator(char[] text, int start, int limit) { 80 if (start < 0 || limit < start || limit > text.length) { 81 throw new IllegalArgumentException(); 82 } 83 84 this.text = text; 85 this.start = this.index = start; 86 this.limit = limit; 87 } 88 89 public void setToStart() { 90 index = start; 91 } 92 93 public void setToLimit() { 94 index = limit; 95 } 96 97 public int next() { 98 if (index < limit) { 99 char cp1 = text[index++]; 100 if (Character.isHighSurrogate(cp1) && index < limit) { 101 char cp2 = text[index]; 102 if (Character.isLowSurrogate(cp2)) { 103 ++index; 104 return Character.toCodePoint(cp1, cp2); 105 } 106 } 107 return cp1; 108 } 109 return DONE; 110 } 111 112 public int prev() { 113 if (index > start) { 114 char cp2 = text[--index]; 115 if (Character.isLowSurrogate(cp2) && index > start) { 116 char cp1 = text[index - 1]; 117 if (Character.isHighSurrogate(cp1)) { 118 --index; 119 return Character.toCodePoint(cp1, cp2); 120 } 121 } 122 return cp2; 123 } 124 return DONE; 125 } 126 127 public int charIndex() { 128 return index; 129 } 130 } 131 132 final class CharSequenceCodePointIterator extends CodePointIterator { 133 private CharSequence text; 134 private int index; 135 136 public CharSequenceCodePointIterator(CharSequence text) { 137 this.text = text; 138 } 139 140 public void setToStart() { 141 index = 0; 142 } 143 144 public void setToLimit() { 145 index = text.length(); 146 } 147 148 public int next() { 149 if (index < text.length()) { 150 char cp1 = text.charAt(index++); 151 if (Character.isHighSurrogate(cp1) && index < text.length()) { 152 char cp2 = text.charAt(index+1); 153 if (Character.isLowSurrogate(cp2)) { 154 ++index; 155 return Character.toCodePoint(cp1, cp2); 156 } 157 } 158 return cp1; 159 } 160 return DONE; 161 } 162 163 public int prev() { 164 if (index > 0) { 165 char cp2 = text.charAt(--index); 166 if (Character.isLowSurrogate(cp2) && index > 0) { 167 char cp1 = text.charAt(index - 1); 168 if (Character.isHighSurrogate(cp1)) { 169 --index; 170 return Character.toCodePoint(cp1, cp2); 171 } 172 } 173 return cp2; 174 } 175 return DONE; 176 } 177 178 public int charIndex() { 179 return index; 180 } 181 } 182 183 // note this has different iteration semantics than CharacterIterator 184 final class CharacterIteratorCodePointIterator extends CodePointIterator { 185 private CharacterIterator iter; 186 187 public CharacterIteratorCodePointIterator(CharacterIterator iter) { 188 this.iter = iter; 189 } 190 191 public void setToStart() { 192 iter.setIndex(iter.getBeginIndex()); 193 } 194 195 public void setToLimit() { 196 iter.setIndex(iter.getEndIndex()); 197 } 198 199 public int next() { 200 char cp1 = iter.current(); 201 if (cp1 != CharacterIterator.DONE) { 202 char cp2 = iter.next(); 203 if (Character.isHighSurrogate(cp1) && cp2 != CharacterIterator.DONE) { 204 if (Character.isLowSurrogate(cp2)) { 205 iter.next(); 206 return Character.toCodePoint(cp1, cp2); 207 } 208 } 209 return cp1; 210 } 211 return DONE; 212 } 213 214 public int prev() { 215 char cp2 = iter.previous(); 216 if (cp2 != CharacterIterator.DONE) { 217 if (Character.isLowSurrogate(cp2)) { 218 char cp1 = iter.previous(); 219 if (Character.isHighSurrogate(cp1)) { 220 return Character.toCodePoint(cp1, cp2); 221 } 222 iter.next(); 223 } 224 return cp2; 225 } 226 return DONE; 227 } 228 229 public int charIndex() { 230 return iter.getIndex(); 231 } 232 }