1. /*
  2. * @(#)StringTokenizer.java 1.20 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. import java.lang.*;
  9. /**
  10. * The string tokenizer class allows an application to break a
  11. * string into tokens. The tokenization method is much simpler than
  12. * the one used by the <code>StreamTokenizer</code> class. The
  13. * <code>StringTokenizer</code> methods do not distinguish among
  14. * identifiers, numbers, and quoted strings, nor do they recognize
  15. * and skip comments.
  16. * <p>
  17. * The set of delimiters (the characters that separate tokens) may
  18. * be specified either at creation time or on a per-token basis.
  19. * <p>
  20. * An instance of <code>StringTokenizer</code> behaves in one of two
  21. * ways, depending on whether it was created with the
  22. * <code>returnTokens</code> flag having the value <code>true</code>
  23. * or <code>false</code>:
  24. * <ul>
  25. * <li>If the flag is <code>false</code>, delimiter characters serve to
  26. * separate tokens. A token is a maximal sequence of consecutive
  27. * characters that are not delimiters.
  28. * <li>If the flag is <code>true</code>, delimiter characters are themselves
  29. * considered to be tokens. A token is thus either one delimiter
  30. * character, or a maximal sequence of consecutive characters that are
  31. * not delimiters.
  32. * </ul><p>
  33. * A <tt>StringTokenizer</tt> object internally maintains a current
  34. * position within the string to be tokenized. Some operations advance this
  35. * current position past the characters processed.<p>
  36. * A token is returned by taking a substring of the string that was used to
  37. * create the <tt>StringTokenizer</tt> object.
  38. * <p>
  39. * The following is one example of the use of the tokenizer. The code:
  40. * <blockquote><pre>
  41. * StringTokenizer st = new StringTokenizer("this is a test");
  42. * while (st.hasMoreTokens()) {
  43. * println(st.nextToken());
  44. * }
  45. * </pre></blockquote>
  46. * <p>
  47. * prints the following output:
  48. * <blockquote><pre>
  49. * this
  50. * is
  51. * a
  52. * test
  53. * </pre></blockquote>
  54. *
  55. * @author unascribed
  56. * @version 1.20, 11/29/01
  57. * @see java.io.StreamTokenizer
  58. * @since JDK1.0
  59. */
  60. public
  61. class StringTokenizer implements Enumeration {
  62. private int currentPosition;
  63. private int maxPosition;
  64. private String str;
  65. private String delimiters;
  66. private boolean retTokens;
  67. /**
  68. * Constructs a string tokenizer for the specified string. All
  69. * characters in the <code>delim</code> argument are the delimiters
  70. * for separating tokens.
  71. * <p>
  72. * If the <code>returnTokens</code> flag is <code>true</code>, then
  73. * the delimiter characters are also returned as tokens. Each
  74. * delimiter is returned as a string of length one. If the flag is
  75. * <code>false</code>, the delimiter characters are skipped and only
  76. * serve as separators between tokens.
  77. *
  78. * @param str a string to be parsed.
  79. * @param delim the delimiters.
  80. * @param returnTokens flag indicating whether to return the delimiters
  81. * as tokens.
  82. */
  83. public StringTokenizer(String str, String delim, boolean returnTokens) {
  84. currentPosition = 0;
  85. this.str = str;
  86. maxPosition = str.length();
  87. delimiters = delim;
  88. retTokens = returnTokens;
  89. }
  90. /**
  91. * Constructs a string tokenizer for the specified string. The
  92. * characters in the <code>delim</code> argument are the delimiters
  93. * for separating tokens. Delimiter characters themselves will not
  94. * be treated as tokens.
  95. *
  96. * @param str a string to be parsed.
  97. * @param delim the delimiters.
  98. */
  99. public StringTokenizer(String str, String delim) {
  100. this(str, delim, false);
  101. }
  102. /**
  103. * Constructs a string tokenizer for the specified string. The
  104. * tokenizer uses the default delimiter set, which is
  105. * <code>"\t\n\r\f"</code>: the space character, the tab
  106. * character, the newline character, the carriage-return character,
  107. * and the form-feed character. Delimiter characters themselves will
  108. * not be treated as tokens.
  109. *
  110. * @param str a string to be parsed.
  111. */
  112. public StringTokenizer(String str) {
  113. this(str, " \t\n\r\f", false);
  114. }
  115. /**
  116. * Skips delimiters.
  117. */
  118. private void skipDelimiters() {
  119. while (!retTokens &&
  120. (currentPosition < maxPosition) &&
  121. (delimiters.indexOf(str.charAt(currentPosition)) >= 0)) {
  122. currentPosition++;
  123. }
  124. }
  125. /**
  126. * Tests if there are more tokens available from this tokenizer's string.
  127. * If this method returns <tt>true</tt>, then a subsequent call to
  128. * <tt>nextToken</tt> with no argument will successfully return a token.
  129. *
  130. * @return <code>true</code> if and only if there is at least one token
  131. * in the string after the current position; <code>false</code>
  132. * otherwise.
  133. */
  134. public boolean hasMoreTokens() {
  135. skipDelimiters();
  136. return (currentPosition < maxPosition);
  137. }
  138. /**
  139. * Returns the next token from this string tokenizer.
  140. *
  141. * @return the next token from this string tokenizer.
  142. * @exception NoSuchElementException if there are no more tokens in this
  143. * tokenizer's string.
  144. */
  145. public String nextToken() {
  146. skipDelimiters();
  147. if (currentPosition >= maxPosition) {
  148. throw new NoSuchElementException();
  149. }
  150. int start = currentPosition;
  151. while ((currentPosition < maxPosition) &&
  152. (delimiters.indexOf(str.charAt(currentPosition)) < 0)) {
  153. currentPosition++;
  154. }
  155. if (retTokens && (start == currentPosition) &&
  156. (delimiters.indexOf(str.charAt(currentPosition)) >= 0)) {
  157. currentPosition++;
  158. }
  159. return str.substring(start, currentPosition);
  160. }
  161. /**
  162. * Returns the next token in this string tokenizer's string. First,
  163. * the set of characters considered to be delimiters by this
  164. * <tt>StringTokenizer</tt> object is changed to be the characters in
  165. * the string <tt>delim</tt>. Then the next token in the string
  166. * after the current position is returned. The current position is
  167. * advanced beyond the recognized token. The new delimiter set
  168. * remains the default after this call.
  169. *
  170. * @param delim the new delimiters.
  171. * @return the next token, after switching to the new delimiter set.
  172. * @exception NoSuchElementException if there are no more tokens in this
  173. * tokenizer's string.
  174. */
  175. public String nextToken(String delim) {
  176. delimiters = delim;
  177. return nextToken();
  178. }
  179. /**
  180. * Returns the same value as the <code>hasMoreTokens</code>
  181. * method. It exists so that this class can implement the
  182. * <code>Enumeration</code> interface.
  183. *
  184. * @return <code>true</code> if there are more tokens;
  185. * <code>false</code> otherwise.
  186. * @see java.util.Enumeration
  187. * @see java.util.StringTokenizer#hasMoreTokens()
  188. */
  189. public boolean hasMoreElements() {
  190. return hasMoreTokens();
  191. }
  192. /**
  193. * Returns the same value as the <code>nextToken</code> method,
  194. * except that its declared return value is <code>Object</code> rather than
  195. * <code>String</code>. It exists so that this class can implement the
  196. * <code>Enumeration</code> interface.
  197. *
  198. * @return the next token in the string.
  199. * @exception NoSuchElementException if there are no more tokens in this
  200. * tokenizer's string.
  201. * @see java.util.Enumeration
  202. * @see java.util.StringTokenizer#nextToken()
  203. */
  204. public Object nextElement() {
  205. return nextToken();
  206. }
  207. /**
  208. * Calculates the number of times that this tokenizer's
  209. * <code>nextToken</code> method can be called before it generates an
  210. * exception. The current position is not advanced.
  211. *
  212. * @return the number of tokens remaining in the string using the current
  213. * delimiter set.
  214. * @see java.util.StringTokenizer#nextToken()
  215. */
  216. public int countTokens() {
  217. int count = 0;
  218. int currpos = currentPosition;
  219. while (currpos < maxPosition) {
  220. /*
  221. * This is just skipDelimiters(); but it does not affect
  222. * currentPosition.
  223. */
  224. while (!retTokens &&
  225. (currpos < maxPosition) &&
  226. (delimiters.indexOf(str.charAt(currpos)) >= 0)) {
  227. currpos++;
  228. }
  229. if (currpos >= maxPosition) {
  230. break;
  231. }
  232. int start = currpos;
  233. while ((currpos < maxPosition) &&
  234. (delimiters.indexOf(str.charAt(currpos)) < 0)) {
  235. currpos++;
  236. }
  237. if (retTokens && (start == currpos) &&
  238. (delimiters.indexOf(str.charAt(currpos)) >= 0)) {
  239. currpos++;
  240. }
  241. count++;
  242. }
  243. return count;
  244. }
  245. }