59 * <blockquote><pre>{@code
60 * Scanner sc = new Scanner(new File("myNumbers"));
61 * while (sc.hasNextLong()) {
62 * long aLong = sc.nextLong();
63 * }
64 * }</pre></blockquote>
65 *
66 * <p>The scanner can also use delimiters other than whitespace. This
67 * example reads several items in from a string:
68 * <blockquote><pre>{@code
69 * String input = "1 fish 2 fish red fish blue fish";
70 * Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
71 * System.out.println(s.nextInt());
72 * System.out.println(s.nextInt());
73 * System.out.println(s.next());
74 * System.out.println(s.next());
75 * s.close();
76 * }</pre></blockquote>
77 * <p>
78 * prints the following output:
79 * <blockqjote><pre>{@code
80 * 1
81 * 2
82 * red
83 * blue
84 * }</pre></blockquote>
85 *
86 * <p>The same output can be generated with this code, which uses a regular
87 * expression to parse all four tokens at once:
88 * <blockquote><pre>{@code
89 * String input = "1 fish 2 fish red fish blue fish";
90 * Scanner s = new Scanner(input);
91 * s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
92 * MatchResult result = s.match();
93 * for (int i=1; i<=result.groupCount(); i++)
94 * System.out.println(result.group(i));
95 * s.close();
96 * }</pre></blockquote>
97 *
98 * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
99 * by a scanner is as recognized by {@link java.lang.Character}.{@link
132 * readable's {@link java.lang.Readable#read} method throws an {@link
133 * java.io.IOException} then the scanner assumes that the end of the input
134 * has been reached. The most recent <tt>IOException</tt> thrown by the
135 * underlying readable can be retrieved via the {@link #ioException} method.
136 *
137 * <p>When a <code>Scanner</code> is closed, it will close its input source
138 * if the source implements the {@link java.io.Closeable} interface.
139 *
140 * <p>A <code>Scanner</code> is not safe for multithreaded use without
141 * external synchronization.
142 *
143 * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
144 * any method of a <code>Scanner</code> will cause a
145 * <code>NullPointerException</code> to be thrown.
146 *
147 * <p>A scanner will default to interpreting numbers as decimal unless a
148 * different radix has been set by using the {@link #useRadix} method. The
149 * {@link #reset} method will reset the value of the scanner's radix to
150 * <code>10</code> regardless of whether it was previously changed.
151 *
152 * <a name="localized-numbers">
153 * <h4> Localized numbers </h4>
154 *
155 * <p> An instance of this class is capable of scanning numbers in the standard
156 * formats as well as in the formats of the scanner's locale. A scanner's
157 * <a name="initial-locale">initial locale </a>is the value returned by the {@link
158 * java.util.Locale#getDefault(Locale.Category)
159 * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
160 * #useLocale} method. The {@link #reset} method will reset the value of the
161 * scanner's locale to the initial locale regardless of whether it was
162 * previously changed.
163 *
164 * <p>The localized formats are defined in terms of the following parameters,
165 * which for a particular locale are taken from that locale's {@link
166 * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
167 * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
168 * <tt>dfs</tt>.
169 *
170 * <blockquote><table>
171 * <tr><td valign="top"><i>LocalGroupSeparator </i></td>
172 * <td valign="top">The character used to separate thousands groups,
173 * <i>i.e.,</i> <tt>dfs.</tt>{@link
174 * java.text.DecimalFormatSymbols#getGroupingSeparator
175 * getGroupingSeparator()}</td></tr>
176 * <tr><td valign="top"><i>LocalDecimalSeparator </i></td>
177 * <td valign="top">The character used for the decimal point,
178 * <i>i.e.,</i> <tt>dfs.</tt>{@link
179 * java.text.DecimalFormatSymbols#getDecimalSeparator
180 * getDecimalSeparator()}</td></tr>
181 * <tr><td valign="top"><i>LocalPositivePrefix </i></td>
182 * <td valign="top">The string that appears before a positive number (may
183 * be empty), <i>i.e.,</i> <tt>df.</tt>{@link
184 * java.text.DecimalFormat#getPositivePrefix
185 * getPositivePrefix()}</td></tr>
186 * <tr><td valign="top"><i>LocalPositiveSuffix </i></td>
187 * <td valign="top">The string that appears after a positive number (may be
188 * empty), <i>i.e.,</i> <tt>df.</tt>{@link
189 * java.text.DecimalFormat#getPositiveSuffix
190 * getPositiveSuffix()}</td></tr>
191 * <tr><td valign="top"><i>LocalNegativePrefix </i></td>
192 * <td valign="top">The string that appears before a negative number (may
193 * be empty), <i>i.e.,</i> <tt>df.</tt>{@link
194 * java.text.DecimalFormat#getNegativePrefix
195 * getNegativePrefix()}</td></tr>
196 * <tr><td valign="top"><i>LocalNegativeSuffix </i></td>
197 * <td valign="top">The string that appears after a negative number (may be
198 * empty), <i>i.e.,</i> <tt>df.</tt>{@link
199 * java.text.DecimalFormat#getNegativeSuffix
200 * getNegativeSuffix()}</td></tr>
201 * <tr><td valign="top"><i>LocalNaN </i></td>
202 * <td valign="top">The string that represents not-a-number for
203 * floating-point values,
204 * <i>i.e.,</i> <tt>dfs.</tt>{@link
205 * java.text.DecimalFormatSymbols#getNaN
206 * getNaN()}</td></tr>
207 * <tr><td valign="top"><i>LocalInfinity </i></td>
208 * <td valign="top">The string that represents infinity for floating-point
209 * values, <i>i.e.,</i> <tt>dfs.</tt>{@link
210 * java.text.DecimalFormatSymbols#getInfinity
211 * getInfinity()}</td></tr>
212 * </table></blockquote>
213 *
214 * <a name="number-syntax">
215 * <h4> Number syntax </h4>
216 *
217 * <p> The strings that can be parsed as numbers by an instance of this class
218 * are specified in terms of the following regular-expression grammar, where
219 * Rmax is the highest digit in the radix being used (for example, Rmax is 9
220 * in base 10).
221 *
222 * <p>
223 * <table cellspacing=0 cellpadding=0 align=center>
224 *
225 * <tr><td valign=top align=right><i>NonASCIIDigit</i> ::</td>
226 * <td valign=top>= A non-ASCII character c for which
227 * {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
228 * returns true</td></tr>
229 *
230 * <tr><td> </td></tr>
231 *
232 * <tr><td align=right><i>Non0Digit</i> ::</td>
233 * <td><tt>= [1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
234 *
235 * <tr><td> </td></tr>
236 *
237 * <tr><td align=right><i>Digit</i> ::</td>
238 * <td><tt>= [0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
239 *
240 * <tr><td> </td></tr>
241 *
242 * <tr><td valign=top align=right><i>GroupedNumeral</i> ::</td>
243 * <td valign=top>
244 * <table cellpadding=0 cellspacing=0>
245 * <tr><td><tt>= ( </tt></td>
246 * <td><i>Non0Digit</i><tt>
247 * </tt><i>Digit</i><tt>?
248 * </tt><i>Digit</i><tt>?</tt></td></tr>
249 * <tr><td></td>
250 * <td><tt>( </tt><i>LocalGroupSeparator</i><tt>
251 * </tt><i>Digit</i><tt>
252 * </tt><i>Digit</i><tt>
253 * </tt><i>Digit</i><tt> )+ )</tt></td></tr>
254 * </table></td></tr>
255 *
256 * <tr><td> </td></tr>
257 *
258 * <tr><td align=right><i>Numeral</i> ::</td>
259 * <td><tt>= ( ( </tt><i>Digit</i><tt>+ )
260 * | </tt><i>GroupedNumeral</i><tt> )</tt></td></tr>
261 *
262 * <tr><td> </td></tr>
263 *
264 * <tr><td valign=top align=right>
265 * <a name="Integer-regex"><i>Integer</i> ::</td>
266 * <td valign=top><tt>= ( [-+]? ( </tt><i>Numeral</i><tt>
267 * ) )</tt></td></tr>
268 * <tr><td></td>
269 * <td><tt>| </tt><i>LocalPositivePrefix</i><tt> </tt><i>Numeral</i><tt>
270 * </tt><i>LocalPositiveSuffix</i></td></tr>
271 * <tr><td></td>
272 * <td><tt>| </tt><i>LocalNegativePrefix</i><tt> </tt><i>Numeral</i><tt>
273 * </tt><i>LocalNegativeSuffix</i></td></tr>
274 *
275 * <tr><td> </td></tr>
276 *
277 * <tr><td align=right><i>DecimalNumeral</i> ::</td>
278 * <td><tt>= </tt><i>Numeral</i></td></tr>
279 * <tr><td></td>
280 * <td><tt>| </tt><i>Numeral</i><tt>
281 * </tt><i>LocalDecimalSeparator</i><tt>
282 * </tt><i>Digit</i><tt>*</tt></td></tr>
283 * <tr><td></td>
284 * <td><tt>| </tt><i>LocalDecimalSeparator</i><tt>
285 * </tt><i>Digit</i><tt>+</tt></td></tr>
286 *
287 * <tr><td> </td></tr>
288 *
289 * <tr><td align=right><i>Exponent</i> ::</td>
290 * <td><tt>= ( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt></td></tr>
291 *
292 * <tr><td> </td></tr>
293 *
294 * <tr><td align=right>
295 * <a name="Decimal-regex"><i>Decimal</i> ::</td>
296 * <td><tt>= ( [-+]? </tt><i>DecimalNumeral</i><tt>
297 * </tt><i>Exponent</i><tt>? )</tt></td></tr>
298 * <tr><td></td>
299 * <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
300 * </tt><i>DecimalNumeral</i><tt>
301 * </tt><i>LocalPositiveSuffix</i>
302 * </tt><i>Exponent</i><tt>?</td></tr>
303 * <tr><td></td>
304 * <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
305 * </tt><i>DecimalNumeral</i><tt>
306 * </tt><i>LocalNegativeSuffix</i>
307 * </tt><i>Exponent</i><tt>?</td></tr>
308 *
309 * <tr><td> </td></tr>
310 *
311 * <tr><td align=right><i>HexFloat</i> ::</td>
312 * <td><tt>= [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
313 * ([pP][-+]?[0-9]+)?</tt></td></tr>
314 *
315 * <tr><td> </td></tr>
316 *
317 * <tr><td align=right><i>NonNumber</i> ::</td>
318 * <td valign=top><tt>= NaN
319 * | </tt><i>LocalNan</i><tt>
320 * | Infinity
321 * | </tt><i>LocalInfinity</i></td></tr>
322 *
323 * <tr><td> </td></tr>
324 *
325 * <tr><td align=right><i>SignedNonNumber</i> ::</td>
326 * <td><tt>= ( [-+]? </tt><i>NonNumber</i><tt> )</tt></td></tr>
327 * <tr><td></td>
328 * <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
329 * </tt><i>NonNumber</i><tt>
330 * </tt><i>LocalPositiveSuffix</i></td></tr>
331 * <tr><td></td>
332 * <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
333 * </tt><i>NonNumber</i><tt>
334 * </tt><i>LocalNegativeSuffix</i></td></tr>
335 *
336 * <tr><td> </td></tr>
337 *
338 * <tr><td valign=top align=right>
339 * <a name="Float-regex"><i>Float</i> ::</td>
340 * <td valign=top><tt>= </tt><i>Decimal</i><tt></td></tr>
341 * <tr><td></td>
342 * <td><tt>| </tt><i>HexFloat</i><tt></td></tr>
343 * <tr><td></td>
344 * <td><tt>| </tt><i>SignedNonNumber</i><tt></td></tr>
345 *
346 * </table>
347 * </center>
348 *
349 * <p> Whitespace is not significant in the above regular expressions.
350 *
351 * @since 1.5
352 */
353 public final class Scanner implements Iterator<String>, Closeable {
354
355 // Internal buffer used to hold input
356 private CharBuffer buf;
357
358 // Size of internal character buffer
359 private static final int BUFFER_SIZE = 1024; // change to 1024;
360
361 // The index into the buffer currently held by the Scanner
362 private int position;
363
364 // Internal matcher used for finding delimiters
365 private Matcher matcher;
366
367 // Pattern used to delimit tokens
368 private Pattern delimPattern;
369
1658 int horizonForLine = endPosition - position;
1659 // If there is nothing between the current pos and the next
1660 // newline simply return null, invoking findWithinHorizon
1661 // with "horizon=0" will scan beyond the line bound.
1662 if (horizonForLine == 0)
1663 return null;
1664 // Search for the pattern
1665 return findWithinHorizon(pattern, horizonForLine);
1666 }
1667
1668 /**
1669 * Attempts to find the next occurrence of a pattern constructed from the
1670 * specified string, ignoring delimiters.
1671 *
1672 * <p>An invocation of this method of the form
1673 * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as
1674 * the invocation
1675 * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1676 *
1677 * @param pattern a string specifying the pattern to search for
1678 * @return the text that matched the specified pattern
1679 * @throws IllegalStateException if this scanner is closed
1680 * @throws IllegalArgumentException if horizon is negative
1681 */
1682 public String findWithinHorizon(String pattern, int horizon) {
1683 return findWithinHorizon(patternCache.forName(pattern), horizon);
1684 }
1685
1686 /**
1687 * Attempts to find the next occurrence of the specified pattern.
1688 *
1689 * <p>This method searches through the input up to the specified
1690 * search horizon, ignoring delimiters. If the pattern is found the
1691 * scanner advances past the input that matched and returns the string
1692 * that matched the pattern. If no such pattern is detected then the
1693 * null is returned and the scanner's position remains unchanged. This
1694 * method may block waiting for input that matches the pattern.
1695 *
1696 * <p>A scanner will never search more than <code>horizon</code> code
1697 * points beyond its current position. Note that a match may be clipped
1698 * by the horizon; that is, an arbitrary match result may have been
1699 * different if the horizon had been larger. The scanner treats the
1700 * horizon as a transparent, non-anchoring bound (see {@link
1701 * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1702 *
1703 * <p>If horizon is <code>0</code>, then the horizon is ignored and
1704 * this method continues to search through the input looking for the
1705 * specified pattern without bound. In this case it may buffer all of
1706 * the input searching for the pattern.
1707 *
1708 * <p>If horizon is negative, then an IllegalArgumentException is
1709 * thrown.
1710 *
1711 * @param pattern the pattern to scan for
1712 * @return the text that matched the specified pattern
1713 * @throws IllegalStateException if this scanner is closed
1714 * @throws IllegalArgumentException if horizon is negative
1715 */
1716 public String findWithinHorizon(Pattern pattern, int horizon) {
1717 ensureOpen();
1718 if (pattern == null)
1719 throw new NullPointerException();
1720 if (horizon < 0)
1721 throw new IllegalArgumentException("horizon < 0");
1722 clearCaches();
1723
1724 // Search for the pattern
1725 while (true) {
1726 String token = findPatternInBuffer(pattern, horizon);
1727 if (token != null) {
1728 matchValid = true;
1729 return token;
1730 }
1731 if (needInput)
|
59 * <blockquote><pre>{@code
60 * Scanner sc = new Scanner(new File("myNumbers"));
61 * while (sc.hasNextLong()) {
62 * long aLong = sc.nextLong();
63 * }
64 * }</pre></blockquote>
65 *
66 * <p>The scanner can also use delimiters other than whitespace. This
67 * example reads several items in from a string:
68 * <blockquote><pre>{@code
69 * String input = "1 fish 2 fish red fish blue fish";
70 * Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
71 * System.out.println(s.nextInt());
72 * System.out.println(s.nextInt());
73 * System.out.println(s.next());
74 * System.out.println(s.next());
75 * s.close();
76 * }</pre></blockquote>
77 * <p>
78 * prints the following output:
79 * <blockquote><pre>{@code
80 * 1
81 * 2
82 * red
83 * blue
84 * }</pre></blockquote>
85 *
86 * <p>The same output can be generated with this code, which uses a regular
87 * expression to parse all four tokens at once:
88 * <blockquote><pre>{@code
89 * String input = "1 fish 2 fish red fish blue fish";
90 * Scanner s = new Scanner(input);
91 * s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
92 * MatchResult result = s.match();
93 * for (int i=1; i<=result.groupCount(); i++)
94 * System.out.println(result.group(i));
95 * s.close();
96 * }</pre></blockquote>
97 *
98 * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
99 * by a scanner is as recognized by {@link java.lang.Character}.{@link
132 * readable's {@link java.lang.Readable#read} method throws an {@link
133 * java.io.IOException} then the scanner assumes that the end of the input
134 * has been reached. The most recent <tt>IOException</tt> thrown by the
135 * underlying readable can be retrieved via the {@link #ioException} method.
136 *
137 * <p>When a <code>Scanner</code> is closed, it will close its input source
138 * if the source implements the {@link java.io.Closeable} interface.
139 *
140 * <p>A <code>Scanner</code> is not safe for multithreaded use without
141 * external synchronization.
142 *
143 * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
144 * any method of a <code>Scanner</code> will cause a
145 * <code>NullPointerException</code> to be thrown.
146 *
147 * <p>A scanner will default to interpreting numbers as decimal unless a
148 * different radix has been set by using the {@link #useRadix} method. The
149 * {@link #reset} method will reset the value of the scanner's radix to
150 * <code>10</code> regardless of whether it was previously changed.
151 *
152 * <h3> <a name="localized-numbers">Localized numbers</a> </h3>
153 *
154 * <p> An instance of this class is capable of scanning numbers in the standard
155 * formats as well as in the formats of the scanner's locale. A scanner's
156 * <a name="initial-locale">initial locale </a>is the value returned by the {@link
157 * java.util.Locale#getDefault(Locale.Category)
158 * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
159 * #useLocale} method. The {@link #reset} method will reset the value of the
160 * scanner's locale to the initial locale regardless of whether it was
161 * previously changed.
162 *
163 * <p>The localized formats are defined in terms of the following parameters,
164 * which for a particular locale are taken from that locale's {@link
165 * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
166 * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
167 * <tt>dfs</tt>.
168 *
169 * <blockquote><dl>
170 * <dt><i>LocalGroupSeparator </i>
171 * <dd>The character used to separate thousands groups,
172 * <i>i.e.,</i> <tt>dfs.</tt>{@link
173 * java.text.DecimalFormatSymbols#getGroupingSeparator
174 * getGroupingSeparator()}
175 * <dt><i>LocalDecimalSeparator </i>
176 * <dd>The character used for the decimal point,
177 * <i>i.e.,</i> <tt>dfs.</tt>{@link
178 * java.text.DecimalFormatSymbols#getDecimalSeparator
179 * getDecimalSeparator()}
180 * <dt><i>LocalPositivePrefix </i>
181 * <dd>The string that appears before a positive number (may
182 * be empty), <i>i.e.,</i> <tt>df.</tt>{@link
183 * java.text.DecimalFormat#getPositivePrefix
184 * getPositivePrefix()}
185 * <dt><i>LocalPositiveSuffix </i>
186 * <dd>The string that appears after a positive number (may be
187 * empty), <i>i.e.,</i> <tt>df.</tt>{@link
188 * java.text.DecimalFormat#getPositiveSuffix
189 * getPositiveSuffix()}
190 * <dt><i>LocalNegativePrefix </i>
191 * <dd>The string that appears before a negative number (may
192 * be empty), <i>i.e.,</i> <tt>df.</tt>{@link
193 * java.text.DecimalFormat#getNegativePrefix
194 * getNegativePrefix()}
195 * <dt><i>LocalNegativeSuffix </i>
196 * <dd>The string that appears after a negative number (may be
197 * empty), <i>i.e.,</i> <tt>df.</tt>{@link
198 * java.text.DecimalFormat#getNegativeSuffix
199 * getNegativeSuffix()}
200 * <dt><i>LocalNaN </i>
201 * <dd>The string that represents not-a-number for
202 * floating-point values,
203 * <i>i.e.,</i> <tt>dfs.</tt>{@link
204 * java.text.DecimalFormatSymbols#getNaN
205 * getNaN()}
206 * <dt><i>LocalInfinity </i>
207 * <dd>The string that represents infinity for floating-point
208 * values, <i>i.e.,</i> <tt>dfs.</tt>{@link
209 * java.text.DecimalFormatSymbols#getInfinity
210 * getInfinity()}
211 * </dl></blockquote>
212 *
213 * <h4> <a name="number-syntax">Number syntax</a> </h4>
214 *
215 * <p> The strings that can be parsed as numbers by an instance of this class
216 * are specified in terms of the following regular-expression grammar, where
217 * Rmax is the highest digit in the radix being used (for example, Rmax is 9 in base 10).
218 *
219 * <p>
220 * <dl>
221 * <dt><i>NonAsciiDigit</i>:
222 * <dd>A non-ASCII character c for which
223 * {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
224 * returns true
225 *
226 * <dt><i>Non0Digit</i>:
227 * <dd><tt>[1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
228 *
229 * <dt><i>Digit</i>:
230 * <dd><tt>[0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
231 *
232 * <dt><i>GroupedNumeral</i>:
233 * <dd><tt>( </tt><i>Non0Digit</i>
234 * <i>Digit</i><tt>?
235 * </tt><i>Digit</i><tt>?</tt>
236 * <dd> <tt>( </tt><i>LocalGroupSeparator</i>
237 * <i>Digit</i>
238 * <i>Digit</i>
239 * <i>Digit</i><tt> )+ )</tt>
240 *
241 * <dt><i>Numeral</i>:
242 * <dd><tt>( ( </tt><i>Digit</i><tt>+ )
243 * | </tt><i>GroupedNumeral</i><tt> )</tt>
244 *
245 * <dt><a name="Integer-regex"><i>Integer</i>:</a>
246 * <dd><tt>( [-+]? ( </tt><i>Numeral</i><tt>
247 * ) )</tt>
248 * <dd><tt>| </tt><i>LocalPositivePrefix</i> <i>Numeral</i>
249 * <i>LocalPositiveSuffix</i>
250 * <dd><tt>| </tt><i>LocalNegativePrefix</i> <i>Numeral</i>
251 * <i>LocalNegativeSuffix</i>
252 *
253 * <dt><i>DecimalNumeral</i>:
254 * <dd><i>Numeral</i>
255 * <dd><tt>| </tt><i>Numeral</i>
256 * <i>LocalDecimalSeparator</i>
257 * <i>Digit</i><tt>*</tt>
258 * <dd><tt>| </tt><i>LocalDecimalSeparator</i>
259 * <i>Digit</i><tt>+</tt>
260 *
261 * <dt><i>Exponent</i>:
262 * <dd><tt>( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt>
263 *
264 * <dt><a name="Decimal-regex"><i>Decimal</i>:</a>
265 * <dd><tt>( [-+]? </tt><i>DecimalNumeral</i>
266 * <i>Exponent</i><tt>? )</tt>
267 * <dd><tt>| </tt><i>LocalPositivePrefix</i>
268 * <i>DecimalNumeral</i>
269 * <i>LocalPositiveSuffix</i>
270 * <i>Exponent</i><tt>?</tt>
271 * <dd><tt>| </tt><i>LocalNegativePrefix</i>
272 * <i>DecimalNumeral</i>
273 * <i>LocalNegativeSuffix</i>
274 * <i>Exponent</i><tt>?</tt>
275 *
276 * <dt><i>HexFloat</i>:
277 * <dd><tt>[-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
278 * ([pP][-+]?[0-9]+)?</tt>
279 *
280 * <dt><i>NonNumber</i>:
281 * <dd><tt>NaN
282 * | </tt><i>LocalNan</i><tt>
283 * | Infinity
284 * | </tt><i>LocalInfinity</i>
285 *
286 * <dt><i>SignedNonNumber</i>:
287 * <dd><tt>( [-+]? </tt><i>NonNumber</i><tt> )</tt>
288 * <dd><tt>| </tt><i>LocalPositivePrefix</i>
289 * <i>NonNumber</i>
290 * <i>LocalPositiveSuffix</i>
291 * <dd><tt>| </tt><i>LocalNegativePrefix</i>
292 * <i>NonNumber</i>
293 * <i>LocalNegativeSuffix</i>
294 *
295 * <dt><a name="Float-regex"><i>Float</i></a>:
296 * <dd><i>Decimal</i>
297 * <tt>| </tt><i>HexFloat</i>
298 * <tt>| </tt><i>SignedNonNumber</i>
299 *
300 * </dl>
301 * <p>Whitespace is not significant in the above regular expressions.
302 *
303 * @since 1.5
304 */
305 public final class Scanner implements Iterator<String>, Closeable {
306
307 // Internal buffer used to hold input
308 private CharBuffer buf;
309
310 // Size of internal character buffer
311 private static final int BUFFER_SIZE = 1024; // change to 1024;
312
313 // The index into the buffer currently held by the Scanner
314 private int position;
315
316 // Internal matcher used for finding delimiters
317 private Matcher matcher;
318
319 // Pattern used to delimit tokens
320 private Pattern delimPattern;
321
1610 int horizonForLine = endPosition - position;
1611 // If there is nothing between the current pos and the next
1612 // newline simply return null, invoking findWithinHorizon
1613 // with "horizon=0" will scan beyond the line bound.
1614 if (horizonForLine == 0)
1615 return null;
1616 // Search for the pattern
1617 return findWithinHorizon(pattern, horizonForLine);
1618 }
1619
1620 /**
1621 * Attempts to find the next occurrence of a pattern constructed from the
1622 * specified string, ignoring delimiters.
1623 *
1624 * <p>An invocation of this method of the form
1625 * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as
1626 * the invocation
1627 * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1628 *
1629 * @param pattern a string specifying the pattern to search for
1630 * @param horizon the search horizon
1631 * @return the text that matched the specified pattern
1632 * @throws IllegalStateException if this scanner is closed
1633 * @throws IllegalArgumentException if horizon is negative
1634 */
1635 public String findWithinHorizon(String pattern, int horizon) {
1636 return findWithinHorizon(patternCache.forName(pattern), horizon);
1637 }
1638
1639 /**
1640 * Attempts to find the next occurrence of the specified pattern.
1641 *
1642 * <p>This method searches through the input up to the specified
1643 * search horizon, ignoring delimiters. If the pattern is found the
1644 * scanner advances past the input that matched and returns the string
1645 * that matched the pattern. If no such pattern is detected then the
1646 * null is returned and the scanner's position remains unchanged. This
1647 * method may block waiting for input that matches the pattern.
1648 *
1649 * <p>A scanner will never search more than <code>horizon</code> code
1650 * points beyond its current position. Note that a match may be clipped
1651 * by the horizon; that is, an arbitrary match result may have been
1652 * different if the horizon had been larger. The scanner treats the
1653 * horizon as a transparent, non-anchoring bound (see {@link
1654 * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1655 *
1656 * <p>If horizon is <code>0</code>, then the horizon is ignored and
1657 * this method continues to search through the input looking for the
1658 * specified pattern without bound. In this case it may buffer all of
1659 * the input searching for the pattern.
1660 *
1661 * <p>If horizon is negative, then an IllegalArgumentException is
1662 * thrown.
1663 *
1664 * @param pattern the pattern to scan for
1665 * @param horizon the search horizon
1666 * @return the text that matched the specified pattern
1667 * @throws IllegalStateException if this scanner is closed
1668 * @throws IllegalArgumentException if horizon is negative
1669 */
1670 public String findWithinHorizon(Pattern pattern, int horizon) {
1671 ensureOpen();
1672 if (pattern == null)
1673 throw new NullPointerException();
1674 if (horizon < 0)
1675 throw new IllegalArgumentException("horizon < 0");
1676 clearCaches();
1677
1678 // Search for the pattern
1679 while (true) {
1680 String token = findPatternInBuffer(pattern, horizon);
1681 if (token != null) {
1682 matchValid = true;
1683 return token;
1684 }
1685 if (needInput)
|