1/* 2 * Copyright (c) 1997, 2008, 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 */ 25package javax.swing.text; 26 27import java.text.CharacterIterator; 28 29/** 30 * A segment of a character array representing a fragment 31 * of text. It should be treated as immutable even though 32 * the array is directly accessible. This gives fast access 33 * to fragments of text without the overhead of copying 34 * around characters. This is effectively an unprotected 35 * String. 36 * <p> 37 * The Segment implements the java.text.CharacterIterator 38 * interface to support use with the i18n support without 39 * copying text into a string. 40 * 41 * @author Timothy Prinzing 42 */ 43public class Segment implements Cloneable, CharacterIterator, CharSequence { 44 45 /** 46 * This is the array containing the text of 47 * interest. This array should never be modified; 48 * it is available only for efficiency. 49 */ 50 public char[] array; 51 52 /** 53 * This is the offset into the array that 54 * the desired text begins. 55 */ 56 public int offset; 57 58 /** 59 * This is the number of array elements that 60 * make up the text of interest. 61 */ 62 public int count; 63 64 private boolean partialReturn; 65 66 /** 67 * Creates a new segment. 68 */ 69 public Segment() { 70 this(null, 0, 0); 71 } 72 73 /** 74 * Creates a new segment referring to an existing array. 75 * 76 * @param array the array to refer to 77 * @param offset the offset into the array 78 * @param count the number of characters 79 */ 80 public Segment(char[] array, int offset, int count) { 81 this.array = array; 82 this.offset = offset; 83 this.count = count; 84 partialReturn = false; 85 } 86 87 /** 88 * Flag to indicate that partial returns are valid. If the flag is true, 89 * an implementation of the interface method Document.getText(position,length,Segment) 90 * should return as much text as possible without making a copy. The default 91 * state of the flag is false which will cause Document.getText(position,length,Segment) 92 * to provide the same return behavior it always had, which may or may not 93 * make a copy of the text depending upon the request. 94 * 95 * @param p whether or not partial returns are valid. 96 * @since 1.4 97 */ 98 public void setPartialReturn(boolean p) { 99 partialReturn = p; 100 } 101 102 /** 103 * Flag to indicate that partial returns are valid. 104 * 105 * @return whether or not partial returns are valid. 106 * @since 1.4 107 */ 108 public boolean isPartialReturn() { 109 return partialReturn; 110 } 111 112 /** 113 * Converts a segment into a String. 114 * 115 * @return the string 116 */ 117 public String toString() { 118 if (array != null) { 119 return new String(array, offset, count); 120 } 121 return ""; 122 } 123 124 // --- CharacterIterator methods ------------------------------------- 125 126 /** 127 * Sets the position to getBeginIndex() and returns the character at that 128 * position. 129 * @return the first character in the text, or DONE if the text is empty 130 * @see #getBeginIndex 131 * @since 1.3 132 */ 133 public char first() { 134 pos = offset; 135 if (count != 0) { 136 return array[pos]; 137 } 138 return DONE; 139 } 140 141 /** 142 * Sets the position to getEndIndex()-1 (getEndIndex() if the text is empty) 143 * and returns the character at that position. 144 * @return the last character in the text, or DONE if the text is empty 145 * @see #getEndIndex 146 * @since 1.3 147 */ 148 public char last() { 149 pos = offset + count; 150 if (count != 0) { 151 pos -= 1; 152 return array[pos]; 153 } 154 return DONE; 155 } 156 157 /** 158 * Gets the character at the current position (as returned by getIndex()). 159 * @return the character at the current position or DONE if the current 160 * position is off the end of the text. 161 * @see #getIndex 162 * @since 1.3 163 */ 164 public char current() { 165 if (count != 0 && pos < offset + count) { 166 return array[pos]; 167 } 168 return DONE; 169 } 170 171 /** 172 * Increments the iterator's index by one and returns the character 173 * at the new index. If the resulting index is greater or equal 174 * to getEndIndex(), the current index is reset to getEndIndex() and 175 * a value of DONE is returned. 176 * @return the character at the new position or DONE if the new 177 * position is off the end of the text range. 178 * @since 1.3 179 */ 180 public char next() { 181 pos += 1; 182 int end = offset + count; 183 if (pos >= end) { 184 pos = end; 185 return DONE; 186 } 187 return current(); 188 } 189 190 /** 191 * Decrements the iterator's index by one and returns the character 192 * at the new index. If the current index is getBeginIndex(), the index 193 * remains at getBeginIndex() and a value of DONE is returned. 194 * @return the character at the new position or DONE if the current 195 * position is equal to getBeginIndex(). 196 * @since 1.3 197 */ 198 public char previous() { 199 if (pos == offset) { 200 return DONE; 201 } 202 pos -= 1; 203 return current(); 204 } 205 206 /** 207 * Sets the position to the specified position in the text and returns that 208 * character. 209 * @param position the position within the text. Valid values range from 210 * getBeginIndex() to getEndIndex(). An IllegalArgumentException is thrown 211 * if an invalid value is supplied. 212 * @return the character at the specified position or DONE if the specified position is equal to getEndIndex() 213 * @since 1.3 214 */ 215 public char setIndex(int position) { 216 int end = offset + count; 217 if ((position < offset) || (position > end)) { 218 throw new IllegalArgumentException("bad position: " + position); 219 } 220 pos = position; 221 if ((pos != end) && (count != 0)) { 222 return array[pos]; 223 } 224 return DONE; 225 } 226 227 /** 228 * Returns the start index of the text. 229 * @return the index at which the text begins. 230 * @since 1.3 231 */ 232 public int getBeginIndex() { 233 return offset; 234 } 235 236 /** 237 * Returns the end index of the text. This index is the index of the first 238 * character following the end of the text. 239 * @return the index after the last character in the text 240 * @since 1.3 241 */ 242 public int getEndIndex() { 243 return offset + count; 244 } 245 246 /** 247 * Returns the current index. 248 * @return the current index. 249 * @since 1.3 250 */ 251 public int getIndex() { 252 return pos; 253 } 254 255 // --- CharSequence methods ------------------------------------- 256 257 /** 258 * {@inheritDoc} 259 * @since 1.6 260 */ 261 public char charAt(int index) { 262 if (index < 0 263 || index >= count) { 264 throw new StringIndexOutOfBoundsException(index); 265 } 266 return array[offset + index]; 267 } 268 269 /** 270 * {@inheritDoc} 271 * @since 1.6 272 */ 273 public int length() { 274 return count; 275 } 276 277 /** 278 * {@inheritDoc} 279 * @since 1.6 280 */ 281 public CharSequence subSequence(int start, int end) { 282 if (start < 0) { 283 throw new StringIndexOutOfBoundsException(start); 284 } 285 if (end > count) { 286 throw new StringIndexOutOfBoundsException(end); 287 } 288 if (start > end) { 289 throw new StringIndexOutOfBoundsException(end - start); 290 } 291 Segment segment = new Segment(); 292 segment.array = this.array; 293 segment.offset = this.offset + start; 294 segment.count = end - start; 295 return segment; 296 } 297 298 /** 299 * Creates a shallow copy. 300 * 301 * @return the copy 302 */ 303 public Object clone() { 304 Object o; 305 try { 306 o = super.clone(); 307 } catch (CloneNotSupportedException cnse) { 308 o = null; 309 } 310 return o; 311 } 312 313 private int pos; 314 315 316} 317