1 /* StringTokenizer -- breaks a String into tokens 2 Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.util; 40 41 /** 42 * This class splits a string into tokens. The caller can set on which 43 * delimiters the string should be split and if the delimiters should be 44 * returned. This is much simpler than {@link java.io.StreamTokenizer}. 45 * 46 * <p>You may change the delimiter set on the fly by calling 47 * nextToken(String). But the semantic is quite difficult; it even 48 * depends on calling <code>hasMoreTokens()</code>. You should call 49 * <code>hasMoreTokens()</code> before, otherwise the old delimiters 50 * after the last token are candidates for being returned. 51 * 52 * <p>If you want to get the delimiters, you have to use the three argument 53 * constructor. The delimiters are returned as token consisting of a 54 * single character. 55 * 56 * @author Jochen Hoenicke 57 * @author Warren Levy (warrenl@cygnus.com) 58 * @see java.io.StreamTokenizer 59 * @status updated to 1.4 60 */ 61 public class StringTokenizer implements Enumeration<Object> 62 { 63 // WARNING: StringTokenizer is a CORE class in the bootstrap cycle. See the 64 // comments in vm/reference/java/lang/Runtime for implications of this fact. 65 66 /** 67 * The position in the str, where we currently are. 68 */ 69 private int pos; 70 71 /** 72 * The string that should be split into tokens. 73 */ 74 private final String str; 75 76 /** 77 * The length of the string. 78 */ 79 private final int len; 80 81 /** 82 * The string containing the delimiter characters. 83 */ 84 private String delim; 85 86 /** 87 * Tells, if we should return the delimiters. 88 */ 89 private final boolean retDelims; 90 91 /** 92 * Creates a new StringTokenizer for the string <code>str</code>, 93 * that should split on the default delimiter set (space, tab, 94 * newline, return and formfeed), and which doesn't return the 95 * delimiters. 96 * 97 * @param str The string to split 98 * @throws NullPointerException if str is null 99 */ StringTokenizer(String str)100 public StringTokenizer(String str) 101 { 102 this(str, " \t\n\r\f", false); 103 } 104 105 /** 106 * Create a new StringTokenizer, that splits the given string on 107 * the given delimiter characters. It doesn't return the delimiter 108 * characters. 109 * 110 * @param str the string to split 111 * @param delim a string containing all delimiter characters 112 * @throws NullPointerException if either argument is null 113 */ StringTokenizer(String str, String delim)114 public StringTokenizer(String str, String delim) 115 { 116 this(str, delim, false); 117 } 118 119 /** 120 * Create a new StringTokenizer, that splits the given string on 121 * the given delimiter characters. If you set 122 * <code>returnDelims</code> to <code>true</code>, the delimiter 123 * characters are returned as tokens of their own. The delimiter 124 * tokens always consist of a single character. 125 * 126 * @param str the string to split 127 * @param delim a string containing all delimiter characters 128 * @param returnDelims tells, if you want to get the delimiters 129 * @throws NullPointerException if str or delim is null 130 */ StringTokenizer(String str, String delim, boolean returnDelims)131 public StringTokenizer(String str, String delim, boolean returnDelims) 132 { 133 len = str.length(); 134 this.str = str; 135 this.delim = delim; 136 this.retDelims = returnDelims; 137 this.pos = 0; 138 } 139 140 /** 141 * Tells if there are more tokens. 142 * 143 * @return true if the next call of nextToken() will succeed 144 */ hasMoreTokens()145 public boolean hasMoreTokens() 146 { 147 if (! retDelims) 148 { 149 while (pos < len && delim.indexOf(str.charAt(pos)) >= 0) 150 pos++; 151 } 152 return pos < len; 153 } 154 155 /** 156 * Returns the nextToken, changing the delimiter set to the given 157 * <code>delim</code>. The change of the delimiter set is 158 * permanent, ie. the next call of nextToken(), uses the same 159 * delimiter set. 160 * 161 * @param delim a string containing the new delimiter characters 162 * @return the next token with respect to the new delimiter characters 163 * @throws NoSuchElementException if there are no more tokens 164 * @throws NullPointerException if delim is null 165 */ nextToken(String delim)166 public String nextToken(String delim) throws NoSuchElementException 167 { 168 this.delim = delim; 169 return nextToken(); 170 } 171 172 /** 173 * Returns the nextToken of the string. 174 * 175 * @return the next token with respect to the current delimiter characters 176 * @throws NoSuchElementException if there are no more tokens 177 */ nextToken()178 public String nextToken() throws NoSuchElementException 179 { 180 if (pos < len && delim.indexOf(str.charAt(pos)) >= 0) 181 { 182 if (retDelims) 183 return str.substring(pos, ++pos); 184 while (++pos < len && delim.indexOf(str.charAt(pos)) >= 0) 185 ; 186 } 187 if (pos < len) 188 { 189 int start = pos; 190 while (++pos < len && delim.indexOf(str.charAt(pos)) < 0) 191 ; 192 193 return str.substring(start, pos); 194 } 195 throw new NoSuchElementException(); 196 } 197 198 /** 199 * This does the same as hasMoreTokens. This is the 200 * <code>Enumeration</code> interface method. 201 * 202 * @return true, if the next call of nextElement() will succeed 203 * @see #hasMoreTokens() 204 */ hasMoreElements()205 public boolean hasMoreElements() 206 { 207 return hasMoreTokens(); 208 } 209 210 /** 211 * This does the same as nextTokens. This is the 212 * <code>Enumeration</code> interface method. 213 * 214 * @return the next token with respect to the current delimiter characters 215 * @throws NoSuchElementException if there are no more tokens 216 * @see #nextToken() 217 */ nextElement()218 public Object nextElement() throws NoSuchElementException 219 { 220 return nextToken(); 221 } 222 223 /** 224 * This counts the number of remaining tokens in the string, with 225 * respect to the current delimiter set. 226 * 227 * @return the number of times <code>nextTokens()</code> will succeed 228 * @see #nextToken() 229 */ countTokens()230 public int countTokens() 231 { 232 int count = 0; 233 int delimiterCount = 0; 234 boolean tokenFound = false; // Set when a non-delimiter is found 235 int tmpPos = pos; 236 237 // Note for efficiency, we count up the delimiters rather than check 238 // retDelims every time we encounter one. That way, we can 239 // just do the conditional once at the end of the method 240 while (tmpPos < len) 241 { 242 if (delim.indexOf(str.charAt(tmpPos++)) >= 0) 243 { 244 if (tokenFound) 245 { 246 // Got to the end of a token 247 count++; 248 tokenFound = false; 249 } 250 delimiterCount++; // Increment for this delimiter 251 } 252 else 253 { 254 tokenFound = true; 255 // Get to the end of the token 256 while (tmpPos < len 257 && delim.indexOf(str.charAt(tmpPos)) < 0) 258 ++tmpPos; 259 } 260 } 261 262 // Make sure to count the last token 263 if (tokenFound) 264 count++; 265 266 // if counting delmiters add them into the token count 267 return retDelims ? count + delimiterCount : count; 268 } 269 } // class StringTokenizer 270