aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/util/StringTokenizer.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/util/StringTokenizer.java')
-rw-r--r--libjava/java/util/StringTokenizer.java331
1 files changed, 204 insertions, 127 deletions
diff --git a/libjava/java/util/StringTokenizer.java b/libjava/java/util/StringTokenizer.java
index 1686a03..ee29940 100644
--- a/libjava/java/util/StringTokenizer.java
+++ b/libjava/java/util/StringTokenizer.java
@@ -1,76 +1,236 @@
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.StringTokenizer
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+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.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
/**
+ * This class splits a string into tokens. The caller can set on which
+ * delimiters the string should be split and if the delimiters should be
+ * returned.
+ *
+ * You may change the delimiter set on the fly by calling
+ * 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
+ * after the last token are returned.
+ *
+ * If you want to get the delimiters, you have to use the three argument
+ * constructor. The delimiters are returned as token consisting of a
+ * single character.
+ *
+ * @author Jochen Hoenicke
* @author Warren Levy <warrenl@cygnus.com>
- * @date August 24, 1998.
- */
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
- * "The Java Language Specification", ISBN 0-201-63451-1
- * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
- * Status: Believed complete and correct
*/
-
public class StringTokenizer implements Enumeration
{
- /* String to be parsed */
- private String inputString;
+ /**
+ * The position in the str, where we currently are.
+ */
+ private int pos;
+ /**
+ * The string that should be split into tokens.
+ */
+ private String str;
+ /**
+ * The string containing the delimiter characters.
+ */
+ private String delim;
+ /**
+ * Tells, if we should return the delimiters.
+ */
+ private boolean retDelims;
+
+ /*{
+ invariant {
+ pos >= 0 :: "position is negative";
+ pos <= str.length() :: "position is out of string";
+ str != null :: "String is null";
+ delim != null :: "Delimiters are null";
+ }
+ } */
+
+ /**
+ * Creates a new StringTokenizer for the string <code>str</code>,
+ * that should split on the default delimiter set (space, tap,
+ * newline, return and formfeed), and which doesn't return the
+ * delimiters.
+ * @param str The string to split.
+ */
+ public StringTokenizer(String str)
+ /*{ require { str != null :: "str must not be null"; } } */
+ {
+ this(str, " \t\n\r\f", false);
+ }
- /* String to be parsed put into a char array for efficient access */
- private char[] chArray;
+ /**
+ * Create a new StringTokenizer, that splits the given string on
+ * the given delimiter characters. It doesn't return the delimiter
+ * characters.
+ *
+ * @param str The string to split.
+ * @param delim A string containing all delimiter characters.
+ */
+ public StringTokenizer(String str, String delim)
+ /*{ require { str != null :: "str must not be null";
+ delim != null :: "delim must not be null"; } } */
+ {
+ this(str, delim, false);
+ }
- /* Set of delimiter characters for separating tokens */
- private String delimiters;
+ /**
+ * 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.
+ *
+ * @param str The string to split.
+ * @param delim A string containing all delimiter characters.
+ * @param returnDelims Tells, if you want to get the delimiters.
+ */
+ public StringTokenizer(String str, String delim, boolean returnDelims)
+ /*{ require { str != null :: "str must not be null";
+ delim != null :: "delim must not be null"; } } */
+ {
+ this.str = str;
+ this.delim = delim;
+ this.retDelims = returnDelims;
+ this.pos = 0;
+ }
- /* Whether delimiters in this instance are treated as tokens themselves */
- private boolean returnDelimiters;
+ /**
+ * Tells if there are more tokens.
+ * @return True, if the next call of nextToken() succeeds, false otherwise.
+ */
+ public boolean hasMoreTokens()
+ {
+ if (!retDelims)
+ {
+ while (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ pos++;
+ }
+ }
+ return pos < str.length();
+ }
- /* Index into the input string to start parsing for the next token */
- private int inputStringIndex;
+ /**
+ * 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.
+ * @param delim a string containing the new delimiter characters.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ */
+ public String nextToken(String delim) throws NoSuchElementException
+ /*{ require { hasMoreTokens() :: "no more Tokens available";
+ ensure { $return != null && $return.length() > 0; } } */
+ {
+ this.delim = delim;
+ return nextToken();
+ }
- public StringTokenizer(String str)
+ /**
+ * Returns the nextToken of the string.
+ * @param delim a string containing the new delimiter characters.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ */
+ public String nextToken() throws NoSuchElementException
+ /*{ require { hasMoreTokens() :: "no more Tokens available";
+ ensure { $return != null && $return.length() > 0; } } */
{
- this(str, " \t\n\r", false);
+ if (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ if (retDelims)
+ return str.substring(pos, ++pos);
+
+ while (++pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ /* empty */
+ }
+ }
+ if (pos < str.length())
+ {
+ int start = pos;
+ while (++pos < str.length() && delim.indexOf(str.charAt(pos)) == -1)
+ {
+ /* empty */
+ }
+ return str.substring(start, pos);
+ }
+ throw new NoSuchElementException();
}
- public StringTokenizer(String str, String delims)
+ /**
+ * This does the same as hasMoreTokens. This is the
+ * <code>Enumeration</code interface method.
+ * @return True, if the next call of nextElement() succeeds, false
+ * otherwise.
+ * @see #hasMoreTokens
+ */
+ public boolean hasMoreElements()
{
- this(str, delims, false);
+ return hasMoreTokens();
}
- public StringTokenizer(String str, String delims, boolean retDelim)
+ /**
+ * This does the same as nextTokens. This is the
+ * <code>Enumeration</code interface method.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ * @see #nextToken
+ */
+ public Object nextElement() throws NoSuchElementException
{
- inputString = str;
- delimiters = delims;
- returnDelimiters = retDelim;
- inputStringIndex = 0;
-
- // Work on a copy of the remaining string in a char array
- // to gain efficiency of using primitives
- chArray = new char[inputString.length()];
- inputString.getChars(0, inputString.length(), chArray, 0);
+ return nextToken();
}
+ /**
+ * This counts the number of remaining tokens in the string, with
+ * respect to the current delimiter set.
+ * @return the number of times <code>nextTokens()</code> will
+ * succeed.
+ * @see #nextToken
+ */
public int countTokens()
{
int count = 0;
int delimiterCount = 0;
boolean tokenFound = false; // Set when a non-delimiter is found
- int offset = inputStringIndex;
+ int tmpPos = pos;
// Note for efficiency, we count up the delimiters rather than check
- // returnDelimiters every time we encounter one. That way, we can
+ // retDelims every time we encounter one. That way, we can
// just do the conditional once at the end of the method
- while (offset < chArray.length)
+ while (tmpPos < str.length())
{
- if (isDelimiter(chArray[offset++]))
+ if (delim.indexOf(str.charAt(tmpPos++)) > -1)
{
if (tokenFound)
{
@@ -86,8 +246,9 @@ public class StringTokenizer implements Enumeration
tokenFound = true;
// Get to the end of the token
- while (offset < chArray.length && !isDelimiter(chArray[offset]))
- offset++;
+ while (tmpPos < str.length()
+ && delim.indexOf(str.charAt(tmpPos)) == -1)
+ ++tmpPos;
}
}
@@ -96,90 +257,6 @@ public class StringTokenizer implements Enumeration
count++;
// if counting delmiters add them into the token count
- return returnDelimiters ? count + delimiterCount : count;
- }
-
- public boolean hasMoreElements()
- {
- return hasMoreTokens();
- }
-
- public boolean hasMoreTokens()
- {
- int offset = inputStringIndex;
-
- while (offset < chArray.length)
- if (!isDelimiter(chArray[offset++]) || returnDelimiters)
- {
- // update the current position with the start of the next token
- inputStringIndex = --offset;
-
- return true;
- }
-
- return false;
- }
-
- public Object nextElement()
- {
- return nextToken();
- }
-
- public String nextToken()
- {
- int offset = inputStringIndex;
- int startSubstr = -1;
-
- // Make sure we have more chars left to parse
- // and then find the start of the next token
- while (offset < chArray.length && startSubstr < 0)
- {
- // Find the start of the token; skipping initial delimiters
- if (!isDelimiter(chArray[offset++]))
- startSubstr = offset - 1;
- else if (returnDelimiters)
- {
- // The single char delimiter is treated as a token
- inputStringIndex = offset; // update the current position
-
- return inputString.substring(offset - 1, inputStringIndex);
- }
- }
-
- // Now look for the end of the token
- while (offset < chArray.length)
- {
- if (isDelimiter(chArray[offset++]))
- {
- // Found the end of token
- inputStringIndex = offset - 1; // update the current position
-
- return inputString.substring(startSubstr, inputStringIndex);
- }
- }
-
- // Got to the end of the string without finding the start of a token
- if (startSubstr < 0)
- throw new NoSuchElementException();
-
- // Got to the end of the string before a delimiter
- inputStringIndex = offset; // update the current position
-
- return inputString.substring(startSubstr, inputStringIndex);
- }
-
- public String nextToken(String delims)
- {
- // First replace with new set of delimiters
- delimiters = delims;
-
- return nextToken();
- }
-
- // This private method could be inlined but the other methods are
- // more readable this way, so we'll take the hit on efficiency.
- private boolean isDelimiter(char ch)
- {
- return delimiters.indexOf(ch, 0) >= 0;
+ return retDelims ? count + delimiterCount : count;
}
}