StringTokenizer.java 8.37 KB
Newer Older
1 2
/* StringTokenizer -- breaks a String into tokens
   Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
Tom Tromey committed
3

Tom Tromey committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */
Tom Tromey committed
37 38 39 40 41


package java.util;

/**
42
 * This class splits a string into tokens.  The caller can set on which
Tom Tromey committed
43
 * delimiters the string should be split and if the delimiters should be
44
 * returned. This is much simpler than {@link java.io.StreamTokenizer}.
Tom Tromey committed
45
 *
46
 * <p>You may change the delimiter set on the fly by calling
Tom Tromey committed
47 48 49
 * nextToken(String).  But the semantic is quite difficult; it even
 * depends on calling <code>hasMoreTokens()</code>.  You should call
 * <code>hasMoreTokens()</code> before, otherwise the old delimiters
50
 * after the last token are candidates for being returned.
Tom Tromey committed
51
 *
52
 * <p>If you want to get the delimiters, you have to use the three argument
Tom Tromey committed
53
 * constructor.  The delimiters are returned as token consisting of a
54
 * single character.
Tom Tromey committed
55 56
 *
 * @author Jochen Hoenicke
Tom Tromey committed
57
 * @author Warren Levy <warrenl@cygnus.com>
58 59
 * @see java.io.StreamTokenizer
 * @status updated to 1.4
Tom Tromey committed
60 61 62
 */
public class StringTokenizer implements Enumeration
{
63 64 65
  // WARNING: StringTokenizer is a CORE class in the bootstrap cycle. See the
  // comments in vm/reference/java/lang/Runtime for implications of this fact.

Tom Tromey committed
66 67 68 69
  /**
   * The position in the str, where we currently are.
   */
  private int pos;
70

Tom Tromey committed
71 72 73
  /**
   * The string that should be split into tokens.
   */
74 75 76 77 78 79 80
  private final String str;

  /**
   * The length of the string.
   */
  private final int len;

Tom Tromey committed
81 82 83 84
  /**
   * The string containing the delimiter characters.
   */
  private String delim;
85

Tom Tromey committed
86 87 88
  /**
   * Tells, if we should return the delimiters.
   */
89
  private final boolean retDelims;
Tom Tromey committed
90 91 92

  /**
   * Creates a new StringTokenizer for the string <code>str</code>,
93
   * that should split on the default delimiter set (space, tab,
Tom Tromey committed
94 95
   * newline, return and formfeed), and which doesn't return the
   * delimiters.
96 97 98
   *
   * @param str The string to split
   * @throws NullPointerException if str is null
Tom Tromey committed
99 100 101 102 103
   */
  public StringTokenizer(String str)
  {
    this(str, " \t\n\r\f", false);
  }
Tom Tromey committed
104

Tom Tromey committed
105
  /**
106
   * Create a new StringTokenizer, that splits the given string on
Tom Tromey committed
107 108 109
   * the given delimiter characters.  It doesn't return the delimiter
   * characters.
   *
110 111 112
   * @param str the string to split
   * @param delim a string containing all delimiter characters
   * @throws NullPointerException if either argument is null
Tom Tromey committed
113 114 115 116 117
   */
  public StringTokenizer(String str, String delim)
  {
    this(str, delim, false);
  }
Tom Tromey committed
118

Tom Tromey committed
119 120 121 122 123 124 125
  /**
   * Create a new StringTokenizer, that splits the given string on
   * the given delimiter characters.  If you set
   * <code>returnDelims</code> to <code>true</code>, the delimiter
   * characters are returned as tokens of their own.  The delimiter
   * tokens always consist of a single character.
   *
126 127 128 129
   * @param str the string to split
   * @param delim a string containing all delimiter characters
   * @param returnDelims tells, if you want to get the delimiters
   * @throws NullPointerException if str or delim is null
Tom Tromey committed
130 131 132
   */
  public StringTokenizer(String str, String delim, boolean returnDelims)
  {
133
    len = str.length();
Tom Tromey committed
134
    this.str = str;
135 136
    // The toString() hack causes the NullPointerException.
    this.delim = delim.toString();
Tom Tromey committed
137 138 139
    this.retDelims = returnDelims;
    this.pos = 0;
  }
Tom Tromey committed
140

Tom Tromey committed
141 142
  /**
   * Tells if there are more tokens.
143 144
   *
   * @return true if the next call of nextToken() will succeed
Tom Tromey committed
145 146 147
   */
  public boolean hasMoreTokens()
  {
148
    if (! retDelims)
Tom Tromey committed
149
      {
150 151
        while (pos < len && delim.indexOf(str.charAt(pos)) >= 0)
          pos++;
Tom Tromey committed
152
      }
153
    return pos < len;
Tom Tromey committed
154
  }
Tom Tromey committed
155

Tom Tromey committed
156 157 158 159 160
  /**
   * Returns the nextToken, changing the delimiter set to the given
   * <code>delim</code>.  The change of the delimiter set is
   * permanent, ie. the next call of nextToken(), uses the same
   * delimiter set.
161 162 163 164 165
   *
   * @param delim a string containing the new delimiter characters
   * @return the next token with respect to the new delimiter characters
   * @throws NoSuchElementException if there are no more tokens
   * @throws NullPointerException if delim is null
Tom Tromey committed
166 167 168 169 170 171
   */
  public String nextToken(String delim) throws NoSuchElementException
  {
    this.delim = delim;
    return nextToken();
  }
Tom Tromey committed
172

Tom Tromey committed
173 174
  /**
   * Returns the nextToken of the string.
175 176 177
   *
   * @return the next token with respect to the current delimiter characters
   * @throws NoSuchElementException if there are no more tokens
Tom Tromey committed
178 179
   */
  public String nextToken() throws NoSuchElementException
Tom Tromey committed
180
  {
181
    if (pos < len && delim.indexOf(str.charAt(pos)) >= 0)
Tom Tromey committed
182
      {
183 184 185
        if (retDelims)
          return str.substring(pos, ++pos);
        while (++pos < len && delim.indexOf(str.charAt(pos)) >= 0);
Tom Tromey committed
186
      }
187
    if (pos < len)
Tom Tromey committed
188
      {
189 190 191 192
        int start = pos;
        while (++pos < len && delim.indexOf(str.charAt(pos)) < 0);

        return str.substring(start, pos);
Tom Tromey committed
193 194
      }
    throw new NoSuchElementException();
Tom Tromey committed
195 196
  }

Tom Tromey committed
197 198 199
  /**
   * This does the same as hasMoreTokens. This is the
   * <code>Enumeration</code interface method.
200 201 202
   *
   * @return true, if the next call of nextElement() will succeed
   * @see #hasMoreTokens()
Tom Tromey committed
203 204
   */
  public boolean hasMoreElements()
Tom Tromey committed
205
  {
Tom Tromey committed
206
    return hasMoreTokens();
Tom Tromey committed
207 208
  }

Tom Tromey committed
209 210 211
  /**
   * This does the same as nextTokens. This is the
   * <code>Enumeration</code interface method.
212 213 214 215
   *
   * @return the next token with respect to the current delimiter characters
   * @throws NoSuchElementException if there are no more tokens
   * @see #nextToken()
Tom Tromey committed
216 217
   */
  public Object nextElement() throws NoSuchElementException
Tom Tromey committed
218
  {
Tom Tromey committed
219
    return nextToken();
Tom Tromey committed
220 221
  }

Tom Tromey committed
222 223 224
  /**
   * This counts the number of remaining tokens in the string, with
   * respect to the current delimiter set.
225 226 227
   *
   * @return the number of times <code>nextTokens()</code> will succeed
   * @see #nextToken()
Tom Tromey committed
228
   */
Tom Tromey committed
229 230 231 232
  public int countTokens()
  {
    int count = 0;
    int delimiterCount = 0;
233
    boolean tokenFound = false; // Set when a non-delimiter is found
Tom Tromey committed
234
    int tmpPos = pos;
Tom Tromey committed
235 236

    // Note for efficiency, we count up the delimiters rather than check
Tom Tromey committed
237
    // retDelims every time we encounter one.  That way, we can
Tom Tromey committed
238
    // just do the conditional once at the end of the method
239
    while (tmpPos < len)
Tom Tromey committed
240
      {
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
        if (delim.indexOf(str.charAt(tmpPos++)) >= 0)
          {
            if (tokenFound)
              {
                // Got to the end of a token
                count++;
                tokenFound = false;
              }
            delimiterCount++; // Increment for this delimiter
          }
        else
          {
            tokenFound = true;
            // Get to the end of the token
            while (tmpPos < len
                   && delim.indexOf(str.charAt(tmpPos)) < 0)
              ++tmpPos;
          }
Tom Tromey committed
259 260
      }

261
    // Make sure to count the last token
Tom Tromey committed
262 263 264 265
    if (tokenFound)
      count++;

    // if counting delmiters add them into the token count
Tom Tromey committed
266
    return retDelims ? count + delimiterCount : count;
Tom Tromey committed
267
  }
268
} // class StringTokenizer