1 /* 2 * Copyright (c) 1996, 2021, 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 Taligent, Inc. 1996, 1997 - All Rights Reserved 28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 29 * 30 * The original version of this source code and documentation 31 * is copyrighted and owned by Taligent, Inc., a wholly-owned 32 * subsidiary of IBM. These materials are provided under terms 33 * of a License Agreement between Taligent and Sun. This technology 34 * is protected by multiple US and International patents. 35 * 36 * This notice and attribution to Taligent may not be removed. 37 * Taligent is a registered trademark of Taligent, Inc. 38 * 39 */ 40 41 package java.text; 42 43 /** 44 * {@code StringCharacterIterator} implements the 45 * {@code CharacterIterator} protocol for a {@code String}. 46 * The {@code StringCharacterIterator} class iterates over the 47 * entire {@code String}. 48 * 49 * @see CharacterIterator 50 * @since 1.1 51 */ 52 53 public final class StringCharacterIterator implements CharacterIterator 54 { 55 private String text; 56 private int begin; 57 private int end; 58 // invariant: begin <= pos <= end 59 private int pos; 60 61 /** 62 * Constructs an iterator with an initial index of 0. 63 * 64 * @param text the {@code String} to be iterated over 65 */ StringCharacterIterator(String text)66 public StringCharacterIterator(String text) 67 { 68 this(text, 0); 69 } 70 71 /** 72 * Constructs an iterator with the specified initial index. 73 * 74 * @param text The String to be iterated over 75 * @param pos Initial iterator position 76 */ StringCharacterIterator(String text, int pos)77 public StringCharacterIterator(String text, int pos) 78 { 79 this(text, 0, text.length(), pos); 80 } 81 82 /** 83 * Constructs an iterator over the given range of the given string, with the 84 * index set at the specified position. 85 * 86 * @param text The String to be iterated over 87 * @param begin Index of the first character 88 * @param end Index of the character following the last character 89 * @param pos Initial iterator position 90 */ StringCharacterIterator(String text, int begin, int end, int pos)91 public StringCharacterIterator(String text, int begin, int end, int pos) { 92 if (text == null) 93 throw new NullPointerException(); 94 this.text = text; 95 96 if (begin < 0 || begin > end || end > text.length()) 97 throw new IllegalArgumentException("Invalid substring range"); 98 99 if (pos < begin || pos > end) 100 throw new IllegalArgumentException("Invalid position"); 101 102 this.begin = begin; 103 this.end = end; 104 this.pos = pos; 105 } 106 107 /** 108 * Reset this iterator to point to a new string. This package-visible 109 * method is used by other java.text classes that want to avoid allocating 110 * new StringCharacterIterator objects every time their setText method 111 * is called. 112 * 113 * @param text The String to be iterated over 114 * @since 1.2 115 */ setText(String text)116 public void setText(String text) { 117 if (text == null) 118 throw new NullPointerException(); 119 this.text = text; 120 this.begin = 0; 121 this.end = text.length(); 122 this.pos = 0; 123 } 124 125 /** 126 * Implements CharacterIterator.first() for String. 127 * @see CharacterIterator#first 128 */ first()129 public char first() 130 { 131 pos = begin; 132 return current(); 133 } 134 135 /** 136 * Implements CharacterIterator.last() for String. 137 * @see CharacterIterator#last 138 */ last()139 public char last() 140 { 141 if (end != begin) { 142 pos = end - 1; 143 } else { 144 pos = end; 145 } 146 return current(); 147 } 148 149 /** 150 * Implements CharacterIterator.setIndex() for String. 151 * @see CharacterIterator#setIndex 152 */ setIndex(int p)153 public char setIndex(int p) 154 { 155 if (p < begin || p > end) 156 throw new IllegalArgumentException("Invalid index"); 157 pos = p; 158 return current(); 159 } 160 161 /** 162 * Implements CharacterIterator.current() for String. 163 * @see CharacterIterator#current 164 */ current()165 public char current() 166 { 167 if (pos >= begin && pos < end) { 168 return text.charAt(pos); 169 } 170 else { 171 return DONE; 172 } 173 } 174 175 /** 176 * Implements CharacterIterator.next() for String. 177 * @see CharacterIterator#next 178 */ next()179 public char next() 180 { 181 if (pos < end - 1) { 182 pos++; 183 return text.charAt(pos); 184 } 185 else { 186 pos = end; 187 return DONE; 188 } 189 } 190 191 /** 192 * Implements CharacterIterator.previous() for String. 193 * @see CharacterIterator#previous 194 */ previous()195 public char previous() 196 { 197 if (pos > begin) { 198 pos--; 199 return text.charAt(pos); 200 } 201 else { 202 return DONE; 203 } 204 } 205 206 /** 207 * Implements CharacterIterator.getBeginIndex() for String. 208 * @see CharacterIterator#getBeginIndex 209 */ getBeginIndex()210 public int getBeginIndex() 211 { 212 return begin; 213 } 214 215 /** 216 * Implements CharacterIterator.getEndIndex() for String. 217 * @see CharacterIterator#getEndIndex 218 */ getEndIndex()219 public int getEndIndex() 220 { 221 return end; 222 } 223 224 /** 225 * Implements CharacterIterator.getIndex() for String. 226 * @see CharacterIterator#getIndex 227 */ getIndex()228 public int getIndex() 229 { 230 return pos; 231 } 232 233 /** 234 * Compares the equality of two StringCharacterIterator objects. 235 * @param obj the StringCharacterIterator object to be compared with. 236 * @return true if the given obj is the same as this 237 * StringCharacterIterator object; false otherwise. 238 */ equals(Object obj)239 public boolean equals(Object obj) 240 { 241 if (this == obj) 242 return true; 243 if (!(obj instanceof StringCharacterIterator that)) 244 return false; 245 246 if (hashCode() != that.hashCode()) 247 return false; 248 if (!text.equals(that.text)) 249 return false; 250 if (pos != that.pos || begin != that.begin || end != that.end) 251 return false; 252 return true; 253 } 254 255 /** 256 * Computes a hashcode for this iterator. 257 * @return A hash code 258 */ hashCode()259 public int hashCode() 260 { 261 return text.hashCode() ^ pos ^ begin ^ end; 262 } 263 264 /** 265 * Creates a copy of this iterator. 266 * @return A copy of this 267 */ clone()268 public Object clone() 269 { 270 try { 271 StringCharacterIterator other 272 = (StringCharacterIterator) super.clone(); 273 return other; 274 } 275 catch (CloneNotSupportedException e) { 276 throw new InternalError(e); 277 } 278 } 279 280 } 281