001/* java.util.Scanner -- Parses primitive types and strings using regexps
002   Copyright (C) 2007  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package java.util;
039
040import java.io.BufferedInputStream;
041import java.io.File;
042import java.io.FileInputStream;
043import java.io.FileNotFoundException;
044import java.io.IOException;
045import java.io.InputStream;
046
047import java.math.BigDecimal;
048import java.math.BigInteger;
049
050import java.nio.ByteBuffer;
051import java.nio.CharBuffer;
052import java.nio.channels.ReadableByteChannel;
053
054import java.text.DecimalFormat;
055import java.text.DecimalFormatSymbols;
056import java.text.NumberFormat;
057import java.text.ParseException;
058
059import java.util.Iterator;
060import java.util.Locale;
061import java.util.regex.MatchResult;
062import java.util.regex.Matcher;
063import java.util.regex.Pattern;
064
065/**
066 * @author E0327023 Hernadi Laszlo
067 */
068public class Scanner 
069  implements Iterator <String>
070{
071  private static final String NOT_LONG = "\" is not a long";    //$NON-NLS-1$
072
073  private static final String ERR_PREFIX = "\"";        //$NON-NLS-1$
074
075  private static final String NOT_INT = "\" is not an integer"; //$NON-NLS-1$
076
077  private static final String NOT_DOUBLE = "\" is not a double";        //$NON-NLS-1$
078
079  private static final String NOT_BYTE = "\" is not a byte";    //$NON-NLS-1$
080
081  private static final String NOT_BOOLEAN = "\" is not a boolean";      //$NON-NLS-1$
082
083  private static final String IS_NOT = "\" is not ";    //$NON-NLS-1$
084
085  private static final String DEFAULT_PATTERN_S = "\\p{javaWhitespace}+";       //$NON-NLS-1$
086
087  private static final Pattern DEFAULT_PATTERN =
088    Pattern.compile (DEFAULT_PATTERN_S);
089
090  private static final String BIG_INTEGER = "BigInteger";       //$NON-NLS-1$
091
092  private final static String NEW_LINE =
093    System.getProperty ("line.separator");
094
095  private IOException lastIOException = null;
096
097  /**
098   * An InputStream source if a Constructor with an InputStream source is called, otherwise it
099   * stays <source> null </source>.
100   */
101  private InputStream bIS = null;
102
103  /**
104   * Length of the input Buffer, which is the maximum bytes to be read at once.
105   */
106  private final int MaxBufferLen = 1000000;
107
108  /**
109   * Minimum buffer length. If there are less chars in the Buffer than this value reading from
110   * source is tried.
111   */
112  private final int MIN_BUF_LEN = 100;
113
114  /**
115   * Maximum number of processed chars in the Buffer. If exeeded, all processed chars from the
116   * beginning of the Buffer will be discarded to save space. The bytes left are copyed into a new
117   * Buffer.
118   */
119  private final int MAX_PREFIX = 10000;
120
121  /**
122   * The Buffer which is used by the Matcher to find given patterns. It is filled up when matcher
123   * hits end or <code> MIN_BUF_LEN </code> is reached.
124   */
125  private String actBuffer = new String ();
126
127  /**
128   * The current radix to use by the methods getNextXXX and hasNextXXX.
129   */
130  private int currentRadix = 10;
131
132  /**
133   * The current locale.
134   * 
135   * @see #useLocale(Locale)
136   * @see #locale()
137   */
138  private Locale actLocale = Locale.getDefault ();
139
140  /**
141   * The current pattern for the matcher.
142   */
143  private Pattern p = DEFAULT_PATTERN;
144
145  /**
146   * The current position in the Buffer, at which the next match should start.
147   */
148  private int actPos = 0;
149
150  /**
151   * A global buffer to save new allocations by reading from source.
152   */
153  private final byte[] tmpBuffer = new byte[this.MaxBufferLen];
154
155  /**
156   * The charsetName to use with the source.
157   */
158  private String charsetName = null;
159
160  /**
161   * The Matcher which is used.
162   */
163  private Matcher myMatcher = this.p.matcher (this.actBuffer);
164
165  /**
166   * The MatchResult is generated at each match, even if match() isn't called.
167   */
168  private MatchResult actResult = null;
169
170  /**
171   * A Readable source if a Constructor with a Readable source is called, otherwise it stays
172   * <source> null </source>.
173   */
174  private Readable readableSource = null;
175  
176  /**
177   * A ReadableByteChannel source if a Constructor with a ReadableByteChannel source is called,
178   * otherwise it stays <source> null </source>.
179   */
180  private ReadableByteChannel rbcSource = null;
181
182  /**
183   * Indicates if the close() method was called.
184   */
185  private boolean isClosed = false;
186  
187  /**
188   * For performance reasons the last Found is saved, if a hasNextXXX method was called.
189   */
190  private String lastFound = null;
191
192  private boolean lastFoundPresent = false;
193
194  private int lastNextPos = 0;
195
196  private int lastPatternHash = 0;
197
198  private int last_RegionStart = 0;
199
200  private int last_RegionEnd = 0;
201
202  private boolean last_anchor = false;
203
204  private boolean last_transparent = false;
205
206  private MatchResult lastResult = null;
207
208  /**
209   * To keep track of the current position in the stream for the toString method, each time
210   * processed chars are removed the amount is added to processedChars.
211   */
212  private int procesedChars = 0;
213
214  /**
215   * needInput is set <code> true </code> before a read method, and if there is no input it blocks
216   * and stays <code>true</code>. Right after a read it is set to <code>false</code>.
217   */
218  private boolean needInput = false;
219
220  private boolean skipped = false;
221
222  /**
223   * <code> {@link #doSkipp} </code> indicates that the found pattern belongs to the result. If
224   * <code> {@link #doSkipp} </code> is false the match result ends at the beginning of the match.
225   * In both cases the current position is set after the pattern, if the found pattern has to be
226   * removed, a nextXXX method is called.
227   */
228  private boolean doSkipp = false;
229
230  /**
231   * Indicates if the last match was valid or not.
232   */
233  private boolean matchValid = false;
234
235  private NumberFormat actFormat = NumberFormat.getInstance (this.actLocale);
236
237  private DecimalFormat df = (DecimalFormat) this.actFormat;
238
239  /**
240   * Indicates if current Locale should be used at the input.
241   */
242  private boolean useLocale = true;
243
244  private DecimalFormatSymbols dfs =
245    new DecimalFormatSymbols (this.actLocale);
246
247  /**
248   * Constructs a new Scanner with the given File as source.
249   * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName.
250   * 
251   * @param source
252   *            The File to use as source.
253   * @throws FileNotFoundException
254   *             If the file is not found an Exception is thrown.
255   */
256  public Scanner (final File source) throws FileNotFoundException       // TESTED
257  {
258    this (source, null);
259  }
260  
261  /**
262   * Constructs a new Scanner with the given File as source. <br>
263   * {@link #Scanner(InputStream, String)} is called with the given charsetName.
264   * 
265   * @param source
266   *            The File to use as source.
267   * @param charsetName
268   *            Current charset name of the file. If charsetName is null it behaves if it was not
269   *            set.
270   * @throws FileNotFoundException
271   *             If the file is not found an Exception is thrown.
272   */
273  public Scanner (final File source,
274                  final String charsetName) throws FileNotFoundException
275  {
276    this (new FileInputStream (source), charsetName);
277  }
278
279  /**
280   * Constructs a new Scanner with the given inputStream. <br>
281   * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName.
282   * 
283   * @param source
284   *            The InputStream to use as source.
285   */
286  public Scanner (final InputStream source)     // TESTED
287  {
288    this (source, null);
289  }
290
291  /**
292   * Constructs a new Scanner with the InputSream and a charsetName. Afterwards the Buffer is
293   * filled.
294   * 
295   * @param source
296   *            The InputStream to use as source.
297   * @param charsetName
298   *            The charsetName to apply on the source's data.
299   */
300  public Scanner (final InputStream source, final String charsetName)
301  {
302    this.bIS = (new BufferedInputStream (source));
303    this.charsetName = charsetName;
304    myFillBuffer ();
305  }
306  
307  /**
308   * Constructs a new Scanner with a Readable input as source.
309   * 
310   * @param source
311   *            The Readable to use as source.
312   */
313  public Scanner (final Readable source)
314  {
315    this.readableSource = source;
316    myFillBuffer ();
317  }
318
319  /**
320   * Constructs a new Scanner with a ReadableByteChannel as
321   * source. Therfore the {@link #Scanner(ReadableByteChannel,
322   * String)} is called with <code> null </code> as charsetName.
323   * 
324   * @param source
325   *            The ReadableByteChannel to use as source.
326   */
327  public Scanner (final ReadableByteChannel source)
328  {
329    this (source, null);
330  }
331
332  /**
333   * Constructs a new Scanner with a ReadableByteChannel as source and
334   * a given charsetName, which is to be applied on it. <br> It also
335   * initiates the main Buffer.
336   * 
337   * @param source
338   *            The ReadableByteChannel to use as source.
339   * @param charsetName
340   *            The charsetName to be applied on the source.
341   */
342  public Scanner (final ReadableByteChannel source, final String charsetName)
343  {
344    this.charsetName = charsetName;
345    this.rbcSource = source;
346    myFillBuffer ();
347  }
348
349  /**
350   * Constructs a new Scanner using the given String as input only.
351   * 
352   * @param source
353   *            The whole String to be used as source.
354   */
355  public Scanner (final String source)  // TESTED
356  {
357    this.actBuffer = new String (source);
358    this.myMatcher.reset (this.actBuffer);
359  }
360
361  /**
362   * Closes this Scanner. If an {@link IOException} occurs it is
363   * catched and is available under {@link #ioException()}.<br> After
364   * the Scanner is closed, all searches will lead to a {@link
365   * IllegalStateException}.
366   */
367  public void close ()         
368  {
369    try
370    {
371      if (this.bIS != null)
372        this.bIS.close ();
373      if (this.rbcSource != null)
374        this.rbcSource.close ();
375      this.isClosed = true;
376    }
377    catch (IOException ioe)
378    {
379      this.lastIOException = ioe;
380    }
381  }
382
383  /**
384   * Returns the current delimiter.
385   * 
386   * @return the current delimiter.
387   */
388  public Pattern delimiter ()   // TESTED
389  {
390    return this.p;
391  }
392
393  /**
394   * Tries to find the pattern in the current line.
395   * 
396   * @param pattern The pattern which should be searched in the
397   * current line of the input.
398   * @throws NoSuchElementException
399   *             If the pattern was not found.
400   * @return If the search was successful, the result or otherwise a
401   *         {@link NoSuchElementException} is thrown.
402   */
403  public String findInLine (final Pattern pattern) throws NoSuchElementException        // TESTED
404  {
405    String tmpStr = myNextLine (false);
406    return myFindPInStr (pattern, tmpStr, 0);
407  }
408  
409  /**
410   * Compiles the given pattern into a {@link Pattern} and calls
411   * {@link #findInLine(Pattern)} with the compiled pattern and
412   * returns whatever it returns.
413   * 
414   * @param pattern
415   *            The pattern which should be matched in the input.
416   * @throws NoSuchElementException
417   *             If the pattern was not found.
418   * @return The match in the current line.
419   */
420  public String findInLine (final String pattern)       // TESTED
421  {
422    return findInLine (Pattern.compile (pattern));
423  }
424
425  /**
426   * Trys to match the pattern within the given horizon.
427   * 
428   * @param pattern
429   *            Pattern to search.
430   * @param horizon
431   * @return The result of the match.
432   * @throws IllegalArgumentException
433   *             if the horizon is negative.
434   * @throws IllegalStateException
435   *             if the Scanner is closed.
436   */
437  public String findWithinHorizon (final Pattern pattern, final int horizon)
438    throws IllegalArgumentException, IllegalStateException
439  {
440    if (horizon < 0)
441      {
442        throw new IllegalArgumentException (horizon + " is negative");
443      }
444
445    if (this.isClosed)
446      {
447        throw new IllegalStateException ("Scanner is closed");
448      }
449
450    // doSkipp is set true to get the matching patern together with the found String
451    this.doSkipp = true;
452    String rc = myFindPInStr (pattern, this.actBuffer, horizon);
453
454    if (rc != null)
455      {
456        this.actPos += rc.length ();
457      }
458
459    return rc;
460  }
461
462  /**
463   * Compile the pattern and call {@link #findWithinHorizon(Pattern,
464   * int)}.
465   * 
466   * @param pattern
467   *            Pattern to search.
468   * @param horizon
469   * @return The result of the match.
470   * @throws IllegalArgumentException
471   *             if the horizon is negative.
472   * @throws IllegalStateException
473   *             if the Scanner is closed.
474   */
475  public String findWithinHorizon (final String pattern, final int horizon)
476    throws IllegalArgumentException, IllegalStateException
477  {
478    return findWithinHorizon (Pattern.compile (pattern), horizon);
479  }
480
481  /**
482   * Checks if there is any next String using the current
483   * delimiter. Therefore the string must not be <code> null </code>
484   * and the length must be greater then 0. If a {@link
485   * NoSuchElementException} is thrown by the search method, it is
486   * catched and false is returned.
487   * 
488   * @return <code> true </code> if there is any result using the current delimiter. This wouldn't
489   *         lead to a {@link NoSuchElementException}.
490   * @throws IllegalStateException
491   *             if the Scanner is closed.
492   */
493  public boolean hasNext () throws IllegalStateException        // TESTED
494  {
495    String tmpStr = null;
496    
497    try
498    {
499      tmpStr = myCoreNext (false, this.p);
500    }
501    catch (NoSuchElementException nf)
502    {
503    }
504
505    if (tmpStr == null || tmpStr.length () <= 0)
506      {
507        return false;
508      }
509    return true;
510  }
511
512  /**
513   * Searches the pattern in the next subString before the next
514   * current delimiter.
515   * 
516   * @param pattern
517   *            The pattern to search for.
518   * @return <code> true </code> if the pattern is found before the current delimiter.
519   * @throws IllegalStateException
520   *             if the Scanner is closed.
521   */
522  public boolean hasNext (final Pattern pattern) throws IllegalStateException   // TESTED
523  {
524    String tmpStr;
525
526      tmpStr = myNext (pattern, false);
527
528    if (tmpStr == null || tmpStr.length () <= 0)
529      {
530        return false;
531      }
532    return true;
533  }
534
535  /**
536   * Compiles the pattern to a {@link Pattern} and calls {@link
537   * #hasNext(Pattern)}.
538   * 
539   * @see #hasNext(Pattern)
540   * @param pattern
541   *            The pattern as string to search for.
542   * @return <code> true </code> if the pattern is found before the current delimiter.
543   * @throws IllegalStateException
544   *             if the Scanner is closed.
545   */
546  public boolean hasNext (final String pattern) throws IllegalStateException    // TESTED
547  {
548    return hasNext (Pattern.compile (pattern));
549  }
550
551  /**
552   * Checks if the string to the next delimiter can be interpreted as
553   * a BigDecimal number. <br> BigDecimal numbers are always tryed
554   * with radix 10.
555   * 
556   * @see #nextBigDecimal()
557   * @return <code> true </code> if the next string is a BigDecimal number.
558   * @throws IllegalStateException
559   *             if the Scanner is closed.
560   */
561  public boolean hasNextBigDecimal () throws IllegalStateException      // TESTED
562  {
563    try
564    {
565      myBigDecimal (false);
566      return true;
567    }
568    catch (InputMismatchException nfe)
569    {
570      return false;
571    }
572  }
573
574  /**
575   * Checks if the string to the next delimiter can be interpreted as
576   * a BigInteger number. <br> Call {@link #hasNextBigInteger(int)}
577   * with the current radix.
578   * 
579   * @see #nextBigInteger()
580   * @return <code> true </code> if the next string is a BigInteger number.
581   * @throws IllegalStateException
582   *             if the Scanner is closed.
583   */
584  public boolean hasNextBigInteger () throws IllegalStateException      // TESTED
585  {
586    return hasNextBigInteger (this.currentRadix);
587  }
588
589  /**
590   * Checks if the string to the next delimiter can be interpreted as
591   * a BigInteger number. <br>
592   * 
593   * @param radix
594   *            The radix to use for this check. The global radix of the Scanner will not be
595   *            changed.
596   * @return <code> true </code> if the next string is a BigInteger number.
597   * @throws IllegalStateException
598   *             if the Scanner is closed.
599   */
600  public boolean hasNextBigInteger (final int radix) throws
601    IllegalStateException
602  {
603    try
604    {
605      myNextBigInteger (radix, false, BIG_INTEGER);
606      return true;
607    }
608    catch (InputMismatchException ime)
609    {
610      return false;
611    }
612  }
613
614  /**
615   * Checks if the next string could be a boolean. The method handles
616   * the input not case sensitiv, so "true" and "TRUE" and even "tRuE"
617   * are <code> true </code>.
618   * 
619   * @see #nextBoolean()
620   * @return Return <code> true </code> if the next string is a boolean.
621   * @throws IllegalStateException
622   *             if the Scanner is closed.
623   */
624  public boolean hasNextBoolean () throws IllegalStateException // TESTED
625  {
626    try
627    {
628      myNextBoolean (false);
629      return true;
630    }
631    catch (InputMismatchException ime)
632    {
633      return false;
634    }
635  }
636
637  /**
638   * Checks if the string to the next delimiter can be interpreted as
639   * a byte number. <br> Calls {@link #hasNextByte(int)} with the
640   * current radix.
641   * 
642   * @see #nextByte()
643   * @return <code> true </code> if the next string is a byte number.
644   * @throws IllegalStateException
645   *             if the Scanner is closed.
646   */
647  public boolean hasNextByte () throws IllegalStateException    // TESTED
648  {
649    return hasNextByte (this.currentRadix);
650  }
651
652  /**
653   * Checks if the string to the next delimiter can be interpreted as
654   * a byte number with the given radix. <br> To check, the private
655   * method {@link #myNextByte(int, boolean)} is called, and if no
656   * error occurs the next string could be a byte.
657   * 
658   * @see #nextByte(int)
659   * @param radix The radix to use for this check. The global radix of
660   * the Scanner will not be changed.
661   * @return <code> true </code> if the next string is a byte number.
662   * @throws IllegalStateException
663   *             if the Scanner is closed.
664   */
665  public boolean hasNextByte (final int radix) throws IllegalStateException
666  {
667    try
668    {
669      myNextByte (radix, false);
670      return true;
671    }
672    catch (InputMismatchException ime)
673    {
674      return false;
675    }
676  }
677
678  /**
679   * Checks if the string to the next delimiter can be interpreted as
680   * a double number. <br> To check, the private method {@link
681   * #myNextDouble(boolean)} is called, and if no error occurs the
682   * next string could be a double.
683   * 
684   * @see #nextDouble()
685   * @return <code> true </code> if the next string is a double number.
686   * @throws IllegalStateException
687   *             if the Scanner is closed.
688   */
689  public boolean hasNextDouble () throws IllegalStateException  // TESTED
690  {
691    try
692    {
693      myNextDouble (false);
694      return true;
695    }
696    catch (InputMismatchException ime)
697    {
698      return false;
699    }
700  }
701
702  /**
703   * Checks if the string to the next delimiter can be interpreted as
704   * a double number. Because every float is a double this is
705   * checked.<br> To check, the private method {@link
706   * #myNextDouble(boolean)} is called, and if no error occurs the
707   * next string could be a double.
708   * 
709   * @see #nextFloat()
710   * @return <code> true </code> if the next string is a double number.
711   * @throws IllegalStateException
712   *             if the Scanner is closed.
713   */
714  public boolean hasNextFloat () throws IllegalStateException   // TESTED
715  {
716    try
717    {
718      myNextDouble (false);
719      // myNextFloat(false);
720      return true;
721    }
722    catch (InputMismatchException ime)
723    {
724      return false;
725    }
726  }
727
728  /**
729   * Checks if the string to the next delimiter can be interpreted as
730   * an int number. <br> To check, the private method {@link
731   * #myNextInt(int, boolean)} is called, and if no error occurs the
732   * next string could be an int.
733   * 
734   * @see #nextInt(int)
735   * @return <code> true </code> if the next string is an int number.
736   * @throws IllegalStateException
737   *             if the Scanner is closed.
738   */
739  public boolean hasNextInt () throws IllegalStateException     // TESTED
740  {
741    return hasNextInt (this.currentRadix);
742  }
743
744  /**
745   * Checks if the string to the next delimiter can be interpreted as
746   * an int number with the given radix. <br> To check, the private
747   * method {@link #myNextInt(int, boolean)} is called, and if no
748   * error occurs the next string could be an int.
749   * 
750   * @see #nextInt(int)
751   * @param radix
752   *            The radix to use for this check. The global radix of the Scanner will not be
753   *            changed.
754   * @return <code> true </code> if the next string is an int number.
755   * @throws IllegalStateException
756   *             if the Scanner is closed.
757   */
758  public boolean hasNextInt (final int radix) throws IllegalStateException
759  {
760    try
761    {
762      myNextInt (radix, false);
763      return true;
764    }
765    catch (InputMismatchException ime)
766    {
767      return false;
768    }
769  }
770
771  /**
772   * Checks if there is a current line, which ends at the next line
773   * break or the end of the input.
774   * 
775   * @return <code> true </code> if there is a current line.
776   * @throws IllegalStateException
777   *             if the Scanner is closed.
778   */
779  public boolean hasNextLine () throws IllegalStateException    // TESTED
780  {
781    return (myNextLine (false) != null);
782  }
783
784  /**
785   * Checks if the string to the next delimiter can be interpreted as
786   * a long number. <br> To check, the private method {@link
787   * #myNextLong(int, boolean)} is called, and if no error occurs the
788   * next string could be a long.
789   * 
790   * @see #nextLong()
791   * @return <code> true </code> if the next string is a long number.
792   * @throws IllegalStateException
793   *             if the Scanner is closed.
794   */
795  public boolean hasNextLong () throws IllegalStateException    // TESTED
796  {
797    return hasNextLong (this.currentRadix);
798  }
799
800  /**
801   * Checks if the string to the next delimiter can be interpreted as
802   * a long number with the given radix. <br> To check, the private
803   * method {@link #myNextLong(int, boolean)} is called, and if no
804   * error occurs the next string could be a long.
805   * 
806   * @see #nextLong(int)
807   * @param radix
808   *            The radix to use for this check. The global radix of the Scanner will not be
809   *            changed.
810   * @return <code> true </code> if the next string is a long number.
811   * @throws IllegalStateException
812   *             if the Scanner is closed.
813   */
814  public boolean hasNextLong (final int radix) throws IllegalStateException
815  {
816    try
817    {
818      myNextLong (radix, false);
819      return true;
820    }
821    catch (InputMismatchException ime)
822    {
823      return false;
824    }
825  }
826
827  /**
828   * Checks if the string to the next delimiter can be interpreted as
829   * a short number with the given radix. <br> To check, the private
830   * method {@link #myNextShort(int, boolean)} is called, and if no
831   * error occurs the next string could be a short.
832   * 
833   * @see #nextShort(int)
834   * @return <code> true </code> if the next string is a short number.
835   * @throws IllegalStateException
836   *             if the Scanner is closed.
837   */
838  public boolean hasNextShort () throws IllegalStateException   // TESTED
839  {
840    return hasNextShort (this.currentRadix);
841  }
842
843  /**
844   * Checks if the string to the next delimiter can be interpreted as
845   * a short number. <br> To check, the private method {@link
846   * #myNextShort(int, boolean)} is called, and if no error occurs the
847   * next string could be a short.
848   * 
849   * @see #nextShort(int)
850   * @param radix
851   *            The radix to use for this check. The global radix of the Scanner will not be
852   *            changed.
853   * @return <code> true </code> if the next string is a short number.
854   * @throws IllegalStateException
855   *             if the Scanner is closed.
856   */
857  public boolean hasNextShort (final int radix) throws IllegalStateException
858  {
859    try
860    {
861      myNextShort (radix, false);
862      return true;
863    }
864    catch (InputMismatchException ime)
865    {
866      return false;
867    }
868  }
869
870  /**
871   * Returns the last {@link IOException} occured.
872   * 
873   * @return Returns the last {@link IOException}.
874   */
875  public IOException ioException ()
876  {
877    return this.lastIOException;
878  }
879
880  /**
881   * Returns the current value of {@link #useLocale}. This is used to
882   * tell the Scanner if it should use the Locale format or just
883   * handle numbers of the default format.
884   * 
885   * @see #setUseLocale(boolean)
886   * @return the useLoclae.
887   */
888  public boolean isUseLocale () // TESTED
889  {
890    return this.useLocale;
891  }
892
893  /**
894   * Returns the current Locale. It is initialized with {@link
895   * Locale#getDefault()}.
896   * 
897   * @see #useLocale(Locale)
898   * @return Returns the current Locale.
899   */
900  public Locale locale ()       // TESTED
901  {
902    return this.actLocale;
903  }
904
905  /**
906   * Returns the last MatchResult found. This is updated after every
907   * successfully search.
908   * 
909   * @return Returns the last {@link MatchResult} found.
910   */
911  public MatchResult match ()   // TESTED
912  {
913    return this.actResult;
914  }
915
916  /**
917   * Uses the current delimiter to find the next string in the
918   * buffer. If a string is found the current position is set after
919   * the delimiter, otherwise a {@link NoSuchElementException} is
920   * thrown. A successful match sets the matchResult.
921   * 
922   * @see #match()
923   * @return Returns the next string of the buffer.
924   * @throws NoSuchElementException
925   *             If no element was found an exception is thrown.
926   * @throws IllegalStateException
927   *             If the Scanner is closed.
928   */
929  public String next () throws NoSuchElementException, IllegalStateException    // TESTED
930  {
931    return myCoreNext (true, this.p);
932  }
933
934  /**
935   * Tries to match the buffer with the given pattern. The current
936   * delimiter will not be changed.
937   * 
938   * @param pattern
939   *            The pattern to match.
940   * @return Returns the next string matching the pattern.
941   * @throws NoSuchElementException
942   *             If no element was found an exception is thrown.
943   * @throws IllegalStateException
944   *             If the Scanner is closed.
945   */
946  public String next (final Pattern pattern) throws NoSuchElementException, IllegalStateException       // TESTED
947  {
948    return myNext (pattern, true);
949  }
950
951  /**
952   * Tries to match the buffer with the given pattern. The current
953   * delimiter will not be changed.  Calls the {@link #next(Pattern)}
954   * with the compiled pattern.
955   * 
956   * @see #next(Pattern)
957   * @param pattern
958   *            The pattern to match.
959   * @return Returns the next string matching the pattern.
960   * @throws NoSuchElementException
961   *             If no element was found an exception is thrown.
962   * @throws IllegalStateException
963   *             If the Scanner is closed.
964   */
965  public String next (final String pattern) throws NoSuchElementException, IllegalStateException        // TESTED
966  {
967    return next (Pattern.compile (pattern));
968  }
969
970  /**
971   * Tries to interpret the next string as a BigDecimal value.
972   * 
973   * @return Returns the BigDecimal value of the next string.
974   * @throws NoSuchElementException
975   *             If no string is found or the string is not a BigDecimal.
976   * @throws IllegalStateException
977   *             If the Scanner is closed.
978   */
979  public BigDecimal nextBigDecimal () throws NoSuchElementException, IllegalStateException      // TESTED
980  {
981    return myBigDecimal (true);
982  }
983
984  /**
985   * Tries to interpret the next string as a BigInteger value. Call
986   * {@link #nextBigInteger(int)} with the current radix as parameter,
987   * and return the value.
988   * 
989   * @see #nextBigInteger(int)
990   * @return Returns the BigInteger value of the next string.
991   * @throws NoSuchElementException
992   *             If no string is found or the string is not a BigInteger.
993   * @throws IllegalStateException
994   *             If the Scanner is closed.
995   */
996  public BigInteger nextBigInteger () throws NoSuchElementException, IllegalStateException      // TESTED
997  {
998    return nextBigInteger (this.currentRadix);
999  }
1000
1001  /**
1002   * Tries to interpret the next string as a BigInteger value with the
1003   * given radix.
1004   * 
1005   * @param radix
1006   *            The radix to be used for this BigInteger. The current radix of the Scanner is not
1007   *            changed.
1008   * @return Returns the BigInteger value of the next string.
1009   * @throws NoSuchElementException
1010   *             If no string is found or the string is not a BigInteger.
1011   * @throws IllegalStateException
1012   *             If the Scanner is closed.
1013   */
1014  public BigInteger nextBigInteger (final int radix) throws
1015    NoSuchElementException, IllegalStateException
1016  {
1017    return myNextBigInteger (radix, true, BIG_INTEGER);
1018  }
1019
1020  /**
1021   * Tries to interpret the next string to the delimiter as a boolean
1022   * value, ignoring case.
1023   * 
1024   * @return Returns the boolean value of the next matching string or throws an exception.
1025   * @throws NoSuchElementException
1026   *             If no string is found or the string is not a boolean.
1027   * @throws IllegalStateException
1028   *             If the Scanner is closed.
1029   */
1030  public boolean nextBoolean () throws NoSuchElementException, IllegalStateException    // TESTED
1031  {
1032    return myNextBoolean (true);
1033  }
1034
1035  /**
1036   * Tries to interpret the next string as a byte value. Call {@link
1037   * #nextByte(int)} with the current radix as parameter, and return
1038   * the value.
1039   * 
1040   * @see #nextByte(int)
1041   * @return Returns the byte value of the next string.
1042   * @throws NoSuchElementException
1043   *             If no string is found or the string is not a byte
1044   * @throws IllegalStateException
1045   *             If the Scanner is closed.
1046   */
1047  public byte nextByte () throws NoSuchElementException, IllegalStateException  // TESTED
1048  {
1049    return nextByte (this.currentRadix);
1050  }
1051
1052  /**
1053   * Tries to interpret the next string as a byte value with the given
1054   * radix.
1055   * 
1056   * @param radix
1057   *            The radix to be used for this byte. The current radix of the Scanner is not
1058   *            changed.
1059   * @return Returns the byte value of the next string.
1060   * @throws NoSuchElementException
1061   *             If no string is found or the string is not a byte.
1062   * @throws IllegalStateException
1063   *             If the Scanner is closed.
1064   */
1065  public byte nextByte (final int radix) throws NoSuchElementException,
1066    IllegalStateException
1067  {
1068    return myNextByte (radix, true);
1069  }
1070
1071  /**
1072   * Tries to interpret the next string as a double value.
1073   * 
1074   * @return Returns the int value of the next string.
1075   * @throws NoSuchElementException
1076   *             If no string is found or the string is not a double.
1077   * @throws IllegalStateException
1078   *             If the Scanner is closed.
1079   */
1080  public double nextDouble () throws NoSuchElementException, IllegalStateException      // TESTED
1081  {
1082    return myNextDouble (true);
1083  }
1084
1085  /**
1086   * Tries to interpret the next string as a double value, and then
1087   * casts down to float.
1088   * 
1089   * @return Returns the int value of the next string.
1090   * @throws NoSuchElementException
1091   *             If no string is found or the string is not a double.
1092   * @throws IllegalStateException
1093   *             If the Scanner is closed.
1094   */
1095  public float nextFloat () throws NoSuchElementException, IllegalStateException        // TESTED
1096  {
1097    return (float) myNextDouble (true);
1098    // return myNextFloat(true);
1099  }
1100
1101  /**
1102   * Tries to interpret the next string as an int value. Calls {@link
1103   * #nextInt(int)} with the current radix as parameter, and return
1104   * the value.
1105   * 
1106   * @see #nextInt(int)
1107   * @return Returns the int value of the next string.
1108   * @throws NoSuchElementException
1109   *             If no string is found or the string is not an int.
1110   * @throws IllegalStateException
1111   *             If the Scanner is closed.
1112   */
1113  public int nextInt () throws NoSuchElementException, IllegalStateException    // TESTED
1114  {
1115    return nextInt (this.currentRadix);
1116  }
1117
1118  /**
1119   * Tries to interpret the next string as an int value with the given
1120   * radix.
1121   * 
1122   * @param radix
1123   *            The radix to be used for this int. The current radix of the Scanner is not changed
1124   * @return Returns the int value of the next string.
1125   * @throws NoSuchElementException
1126   *             If no string is found or the string is not an int.
1127   * @throws IllegalStateException
1128   *             If the Scanner is closed.
1129   */
1130  public int nextInt (final int radix) throws NoSuchElementException,
1131    IllegalStateException
1132  {
1133    return myNextInt (radix, true);
1134  }
1135
1136  /**
1137   * Tries to match the system line seperator, and returns the current
1138   * line.
1139   * 
1140   * @return Returns the current line.
1141   * @throws NoSuchElementException
1142   *             If the current delimiter is not found.
1143   * @throws IllegalStateException
1144   *             If the Scanner is closed.
1145   */
1146  public String nextLine () throws NoSuchElementException, IllegalStateException        // TESTED
1147  {
1148    return myNextLine (true);
1149  }
1150
1151  /**
1152   * Tries to interpret the next string as a long value. Calls {@link
1153   * #nextLong(int)} with the current radix as parameter, and return
1154   * the value.
1155   * 
1156   * @see #nextLong(int)
1157   * @return Returns the long value of the next string.
1158   * @throws NoSuchElementException
1159   *             If no string is found or the string is not a long.
1160   * @throws IllegalStateException
1161   *             If the Scanner is closed.
1162   */
1163  public long nextLong () throws NoSuchElementException, IllegalStateException  // TESTED
1164  {
1165    return nextLong (this.currentRadix);
1166  }
1167
1168  /**
1169   * Tries to interpret the next string as a long value with the given
1170   * radix.
1171   * 
1172   * @param radix
1173   *            The radix to be used for this long. The current radix of the Scanner is not
1174   *            changed
1175   * @return Returns the long value of the next string.
1176   * @throws NoSuchElementException
1177   *             If no string is found or the string is not a long.
1178   * @throws IllegalStateException
1179   *             If the Scanner is closed.
1180   */
1181  public long nextLong (final int radix) throws NoSuchElementException,
1182    IllegalStateException
1183  {
1184    return myNextLong (radix, true);
1185  }
1186
1187  /**
1188   * Tries to interpret the next string as a short value. Calls {@link
1189   * #nextShort(int)} with the current radix as parameter, and return
1190   * the value.
1191   * 
1192   * @see #nextShort(int)
1193   * @return Returns the short value of the next string.
1194   * @throws NoSuchElementException
1195   *             If no string is found or the string is not a short.
1196   */
1197  public short nextShort () throws NoSuchElementException       // TESTED
1198  {
1199    return nextShort (this.currentRadix);
1200  }
1201
1202  /**
1203   * Tries to interpret the next string as a short value with the
1204   * given radix.
1205   * 
1206   * @param radix
1207   *            The radix to be used for this short. The current radix of the Scanner is not
1208   *            changed.
1209   * @return Returns the short value of the next string.
1210   * @throws NoSuchElementException
1211   *             If no string is found or the string is not a short.
1212   */
1213  public short nextShort (final int radix) throws NoSuchElementException
1214  {
1215    return myNextShort (radix, true);
1216  }
1217
1218  /**
1219   * @return Returns the current radix.
1220   */
1221  public int radix ()
1222  {
1223    return this.currentRadix;
1224  }
1225
1226  /**
1227   * The remove operation is not supported by this implementation of
1228   * Iterator.
1229   */
1230  public void remove ()
1231  {
1232  }
1233
1234  /**
1235   * @param useLocale the useLocale to set.
1236   */
1237  public void setUseLocale (final boolean useLocale)    // TESTED
1238  {
1239    this.useLocale = useLocale;
1240  }
1241
1242  /**
1243   * Skips the given pattern. Sets skipped <code>true</code>.
1244   * 
1245   * @param pattern
1246   *            Pattern which should be skipped.
1247   * @return <code>this</code> with the skipped buffer.
1248   * @throws NoSuchElementException
1249   *             If the Pattern is not found.
1250   */
1251  public Scanner skip (final Pattern pattern) throws NoSuchElementException
1252  {
1253    this.doSkipp = true;
1254    int end;
1255    boolean found;
1256    Matcher matcher = pattern.matcher (this.actBuffer);
1257      matcher.region (this.actPos - 1, this.actBuffer.length ());
1258
1259      found = matcher.find ();
1260      found = myFillBuffer_loop (matcher, this.actPos - 1, found);
1261      end = matcher.end ();
1262
1263      this.actPos = end + 1;
1264
1265      this.doSkipp = false;
1266      this.skipped = true;
1267
1268      actResult = null;
1269
1270    if (!found)
1271      {
1272        throw new NoSuchElementException ();
1273      }
1274    return this;
1275  }
1276
1277  /**
1278   * Skips a given pattern. Calls {@link #skip(Pattern)} with the
1279   * compiled pattern.
1280   * 
1281   * @see #skip(Pattern)
1282   * @param pattern
1283   *            Pattern which should be skipped.
1284   * @return <code>this</code> with the skipped buffer.
1285   */
1286  public Scanner skip (final String pattern)
1287  {
1288    return skip (Pattern.compile (pattern));
1289  }
1290
1291  /**
1292   * Returns the string representation of this Scanner.
1293   */
1294  @Override 
1295    public String toString ()
1296  {
1297    String tmpStr2;
1298    String rc = this.getClass ().getName ();
1299    tmpStr2 = rc;
1300    tmpStr2 = "[delimiters=" + this.p.pattern () + "]";
1301    rc += tmpStr2;
1302    tmpStr2 = "[position=" + (this.procesedChars + this.actPos) + "]";
1303    rc += tmpStr2;
1304    tmpStr2 = "[match valid=" + this.matchValid + "]";
1305    rc += tmpStr2;
1306    tmpStr2 = "[need input=" + this.needInput + "]";
1307    rc += tmpStr2;
1308    tmpStr2 = "[source closed=" + this.isClosed + "]";
1309    rc += tmpStr2;
1310    tmpStr2 = "[skipped=" + this.skipped + "]";
1311    rc += tmpStr2;
1312    tmpStr2 = "[group separator=\\" + this.dfs.getGroupingSeparator () + "]";
1313    rc += tmpStr2;
1314    tmpStr2 = "[decimal separator=\\" + this.dfs.getDecimalSeparator () + "]";
1315    rc += tmpStr2;
1316    tmpStr2 =
1317      "[positive prefix=" + myConvert (this.df.getPositivePrefix ()) + "]";
1318    rc += tmpStr2;
1319    tmpStr2 =
1320      "[negative prefix=" + myConvert (this.df.getNegativePrefix ()) + "]";
1321    rc += tmpStr2;
1322    tmpStr2 =
1323      "[positive suffix=" + myConvert (this.df.getPositiveSuffix ()) + "]";
1324    rc += tmpStr2;
1325    tmpStr2 =
1326      "[negative suffix=" + myConvert (this.df.getNegativeSuffix ()) + "]";
1327    rc += tmpStr2;
1328    tmpStr2 = "[NaN string=" + myConvert (this.dfs.getNaN ()) + "]";
1329    rc += tmpStr2;
1330    tmpStr2 = "[infinity string=" + myConvert (this.dfs.getInfinity ()) + "]";
1331    rc += tmpStr2;
1332    return rc;
1333  }
1334
1335  /**
1336   * Sets the current pattern to the given parameter, and updates the
1337   * {@link Matcher} with the new pattern.
1338   * 
1339   * @param pattern
1340   *            The new pattern to use.
1341   * @return Returns the Scanner (<code>this</code>) with the new pattern.
1342   */
1343  public Scanner useDelimiter (final Pattern pattern)   // TESTED
1344  {
1345    if (pattern != null)
1346      {
1347        this.p = pattern;
1348        this.myMatcher = this.p.matcher (this.actBuffer);
1349      }
1350    return this;
1351  }
1352
1353  /**
1354   * Sets the current pattern to the given parameter. Compiles the
1355   * pattern and calls {@link #useDelimiter(Pattern)}
1356   * 
1357   * @see #useDelimiter(Pattern)
1358   * @param pattern
1359   *            The new pattern to use.
1360   * @return Returns the Scanner (<code>this</code>) with the new pattern.
1361   */
1362  public Scanner useDelimiter (final String pattern)    // TESTED
1363  {
1364    return useDelimiter (Pattern.compile (pattern));
1365  }
1366
1367  /**
1368   * Sets the current Locale to the given parameter. Formats and
1369   * Symbols are also set using the new Locale.
1370   * 
1371   * @param locale The new Locale to use. If it is <code>null</code>
1372   * nothing happens.
1373   * @return Returns the Scanner (<code>this</code>) with the new Locale.
1374   */
1375  public Scanner useLocale (final Locale locale)        // TESTED
1376  {
1377    if (locale != null)
1378      {
1379        this.actLocale = locale;
1380        this.actFormat = NumberFormat.getInstance (this.actLocale);
1381        this.dfs = new DecimalFormatSymbols (this.actLocale);
1382        this.df = (DecimalFormat) this.actFormat;
1383      }
1384    return this;
1385  }
1386
1387  /**
1388   * Sets the current radix to the current value if the given radix is
1389   * >= 2 and <= 36 otherwise an {@link IllegalArgumentException} is
1390   * thrown.
1391   * 
1392   * @param radix
1393   *            the new radix to use as default.
1394   * @return <code> this </code> with the new radix value.
1395   * @throws IllegalArgumentException
1396   *             When the given radix is out of bounds.
1397   */
1398  public Scanner useRadix (final int radix) throws IllegalArgumentException
1399  {
1400    if (radix < 2 || radix > 36)
1401      {
1402        throw new IllegalArgumentException ();
1403      }
1404    this.currentRadix = radix;
1405    return this;
1406  }
1407
1408  /**
1409   * Checks if it is necessary to apply the current Locale on the
1410   * String. If so the String is converted using the {@link
1411   * NumberFormat#parse(String)} into a Number and then back to a
1412   * default stringrepresentation of that Number.
1413   * 
1414   * @see #setUseLocale(boolean)
1415   * @param str
1416   *            String to convert into another string.
1417   * @param radix Radix of the Number in the original string. It has
1418   * to be 10 for anything to happen.
1419   * @return Eighter the Stringrepresention of the number without the
1420   * Locale or an unchanged string.
1421   * @throws ParseException
1422   *             if {@link NumberFormat#parse(String)} fails to parse.
1423   */
1424  private String myApplyLocale (final String str,
1425                                final int radix) throws ParseException
1426  {
1427    String rc;
1428
1429    if (this.useLocale && radix == 10)
1430      {
1431        rc = this.actFormat.parse (str).toString ();
1432        return rc;
1433      }
1434
1435    return str;
1436  }
1437
1438  /**
1439   * If {@link #useLocale} is set and radix is 10 the string is tryed
1440   * to be converted to string without Locale settings, because the
1441   * "normal" convert from Local has only double precision and it is
1442   * not enough for the about 50 digits of precision of the
1443   * BigDecimal. So in the first step the string is seperated into the
1444   * integer part which is converted to a long, and the fraction part
1445   * is appended afterwards. Between the integer and the fraction part
1446   * comes a ".". Finally the resulting string is returned.
1447   * 
1448   * @see #setUseLocale(boolean)
1449   * @param str String representation of a BigDecimal number.
1450   * @return The default String representation (without Locale) of the
1451   * BigInteger.
1452   * @throws ParseException
1453   *             If the String has more than one decimal seperators a parse exception is thrown.
1454   */
1455  private String myApplyLocaleBD (final String str) throws ParseException
1456  {
1457    if (!this.useLocale || this.currentRadix != 10)
1458      {
1459        return str;
1460      }
1461
1462    String negPrefix = this.df.getNegativePrefix ();
1463    String negSuffix = this.df.getNegativeSuffix ();
1464    String posPrefix = this.df.getPositivePrefix ();
1465    String posSuffix = this.df.getPositiveSuffix ();
1466
1467    char d = this.dfs.getDecimalSeparator ();
1468    int begin1, begin2;
1469    boolean isNegativ = false;
1470    String parts = null;
1471
1472    String tmpStr1 = "";
1473
1474    begin1 = str.indexOf (d);
1475    begin2 = str.indexOf (d, begin1 + 1);
1476
1477    if (begin2 > 0)
1478      {
1479        throw new ParseException ("more than one Decimal seperators", begin2);
1480      }
1481
1482    parts = str.substring (0, begin1);
1483
1484    if ((negPrefix.length () > 0
1485         && str.substring (0, negPrefix.length ()).equals (negPrefix))
1486        || (negSuffix.length () > 0
1487            && str.substring (str.length () -
1488                              negSuffix.length ()).equals (negSuffix)))
1489      {
1490        parts += negSuffix;
1491        isNegativ = true;
1492      }
1493    else
1494      if ((posPrefix.length () > 0
1495           && str.substring (0, posPrefix.length ()).equals (posPrefix))
1496          || (posSuffix.length () > 0
1497              && str.substring (str.length () -
1498                                posSuffix.length ()).equals (posSuffix)))
1499      {
1500        parts += posSuffix;
1501      }
1502
1503    tmpStr1 = this.actFormat.parse (parts).toString ();
1504
1505    if (isNegativ)
1506      {
1507        tmpStr1 +=
1508          "." + str.substring (str.indexOf (d) + 1,
1509                               str.length () - negSuffix.length ());
1510      }
1511    else
1512      {
1513        tmpStr1 +=
1514          "." + str.substring (str.indexOf (d) + 1,
1515                               str.length () - posSuffix.length ());
1516      }
1517
1518    return tmpStr1;
1519  }
1520
1521  /**
1522   * Tries to interpret the next String as a BigDecimal. Therfore the
1523   * next String is get with {@link #myCoreNext(boolean, Pattern)} and
1524   * then {@link #myApplyLocaleBD(String)} is called to convert the
1525   * String into a BigDecimal.
1526   * 
1527   * @param delete
1528   *            Should the found string be deleted or not.
1529   * @return Returns the BigDecimal value of the next string.
1530   * @throws InputMismatchException
1531   *             If the string is not a BigDecimal
1532   */
1533  private BigDecimal myBigDecimal (final boolean delete) throws
1534    InputMismatchException
1535  {
1536    BigDecimal rc;
1537    String tmp = myCoreNext (delete, this.p);
1538      try
1539    {
1540      tmp = myApplyLocaleBD (tmp);
1541    }
1542    catch (ParseException e)
1543    {
1544      throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT +
1545                                        "BigDecimal!!");
1546    }
1547    rc = new BigDecimal (tmp);
1548
1549    return rc;
1550  }
1551
1552  /**
1553   * Applies suffix ("\E") and prefix ("\Q") if str.length != 0 Used
1554   * by the toString method.
1555   * 
1556   * @param str
1557   *            the string on which the suffix and prefix should be applied.
1558   * @return The new new string with the suffix and prefix.
1559   */
1560  private String myConvert (final String str)
1561  {
1562    if (str != null && str.length () > 0)
1563      {
1564        return "\\Q" + str + "\\E";
1565      }
1566    return str;
1567  }
1568
1569  /**
1570   * Searches the current Matcher for the current Pattern. If the end
1571   * is reached during the search it tried to read again from the
1572   * source. The search results are always saved in {@link #actResult}
1573   * which is returned when match() is called. If doSkip is true the
1574   * pattern is also taken.
1575   * 
1576   * @param delete
1577   *            if true the aktPos is set.
1578   * @param pattern
1579   *            pattern to search for.
1580   * @return Returns the String which matches the pattern.
1581   * @throws NoSuchElementException
1582   *             If the search has no result.
1583   */
1584  private String myCoreNext (final boolean delete, final Pattern pattern)
1585    throws NoSuchElementException
1586  {
1587    if (this.isClosed)
1588      {
1589        throw new IllegalStateException ("Scanner closed");
1590      }
1591    if (shallUseLastFound (pattern != null ? pattern : this.p))
1592      {
1593        if (this.last_RegionEnd != this.myMatcher.regionEnd ())
1594          {
1595            System.out.println (this.last_RegionEnd + " != " +
1596                                this.myMatcher.regionEnd () + " (" +
1597                                (this.last_RegionEnd -
1598                                 this.myMatcher.regionEnd ()) + ")");
1599          }
1600        if (delete)
1601          {
1602            this.actPos = this.lastNextPos;
1603            this.lastFoundPresent = false;
1604            this.actResult = this.lastResult;
1605          }
1606        return this.lastFound;
1607      }
1608
1609    boolean found = false;
1610    int left;
1611    int endIndex;
1612
1613    String tmp2 = null;
1614
1615    if (this.actPos > this.MAX_PREFIX)
1616      {
1617        // skipp the processed chars so that the size of the buffer don't grow to much even with
1618        // huge files
1619        this.procesedChars += this.actPos;
1620        this.actBuffer = this.actBuffer.substring (this.actPos);
1621        this.actPos = 0;
1622        this.myMatcher = pattern.matcher (this.actBuffer);
1623      }
1624
1625    left = this.actBuffer.length () - this.actPos;
1626    if (left < this.MIN_BUF_LEN)
1627      {
1628        myFillBuffer ();
1629      }
1630    found = this.myMatcher.find (this.actPos);
1631
1632    found = myFillBuffer_loop (this.myMatcher, this.actPos, found);
1633
1634    this.needInput = false;
1635
1636    if (found)
1637      {
1638        if (this.doSkipp)
1639          {
1640            endIndex = this.myMatcher.end ();
1641          }
1642        else
1643          {
1644            endIndex = this.myMatcher.start ();
1645          }
1646        tmp2 = this.actBuffer.substring (this.actPos, endIndex);
1647        this.lastNextPos = this.myMatcher.end ();
1648        /*
1649         * if the delete flag is set, just set the current position after the end of the matched
1650         * pattern.
1651         */
1652        if (delete)
1653          {
1654            this.actPos = this.lastNextPos;
1655          }
1656        else
1657          {
1658            this.lastFound = tmp2;
1659            this.lastFoundPresent = true;
1660            this.lastPatternHash = pattern.hashCode ();
1661          }
1662        this.last_RegionStart = this.myMatcher.regionStart ();
1663        this.last_RegionEnd = this.myMatcher.regionEnd ();
1664        this.last_anchor = this.myMatcher.hasAnchoringBounds ();
1665        this.last_transparent = this.myMatcher.hasTransparentBounds ();
1666      }
1667    else if (this.myMatcher.hitEnd ())
1668      // the end of input is matched
1669      {
1670        tmp2 = this.actBuffer.substring (this.actPos);
1671        this.lastNextPos = this.actBuffer.length ();
1672        if (delete)
1673          {
1674            this.actPos = this.lastNextPos;
1675          }
1676        else
1677          {
1678            this.lastFound = tmp2;
1679            this.lastFoundPresent = true;
1680            this.lastPatternHash = pattern.hashCode ();
1681          }
1682        this.last_RegionStart = this.myMatcher.regionStart ();
1683        this.last_RegionEnd = this.myMatcher.regionEnd ();
1684        this.last_anchor = this.myMatcher.hasAnchoringBounds ();
1685        this.last_transparent = this.myMatcher.hasTransparentBounds ();
1686      }
1687    else
1688      {
1689        /*
1690         * if no match found an Exception is throwed
1691         */
1692        throw new NoSuchElementException ();
1693      }
1694    /*
1695     * change the Result only when a nextXXX() method was called, not if a hasNextXXX() method
1696     * is called
1697     */
1698    if (delete)
1699      {
1700        this.actResult = this.myMatcher.toMatchResult ();
1701
1702        this.matchValid = this.actResult != null;
1703      }
1704    else
1705      {
1706        this.lastResult = this.myMatcher.toMatchResult ();
1707      }
1708
1709    this.skipped = this.doSkipp;
1710    this.doSkipp = false;
1711
1712    return tmp2;
1713  }
1714
1715  /**
1716   * Used to fill the String buffer from a source. Therfore the 3
1717   * possible sources are checked if they are not <code>null</code>
1718   * and this not used, otherwise the read method is called on the
1719   * source. If a charsetName is set and not <code>null</code> it is
1720   * applied to convert to String.
1721   */
1722  private void myFillBuffer ()
1723  {
1724    int len;
1725    String tmpStr;
1726    CharBuffer cb = null;
1727    ByteBuffer bb = null;
1728
1729    if (this.bIS != null)
1730      {
1731        try
1732        {
1733          len = this.bIS.read (this.tmpBuffer);
1734          if (len < 0)
1735            {
1736              return;
1737            }
1738          if (this.charsetName != null)
1739            {
1740              tmpStr = new String (this.tmpBuffer, 0, len, this.charsetName);
1741            }
1742          else
1743            {
1744              tmpStr = new String (this.tmpBuffer, 0, len);
1745            }
1746          this.actBuffer += tmpStr;
1747        }
1748        catch (IOException e)
1749        {
1750          this.lastIOException = e;
1751        }
1752      }
1753    else if (this.readableSource != null)
1754      {
1755        try
1756        {
1757          cb = CharBuffer.allocate (1000);
1758          this.needInput = true;
1759          len = this.readableSource.read (cb);
1760          if (len < 0)
1761            {
1762              return;
1763            }
1764          this.needInput = false;
1765          tmpStr = new String (cb.array ());
1766          this.actBuffer += tmpStr;
1767        }
1768        catch (IOException e)
1769        {
1770          this.lastIOException = e;
1771        }
1772      }
1773    else if (this.rbcSource != null)
1774      {
1775        try
1776        {
1777          bb = ByteBuffer.allocate (1000);
1778          this.needInput = true;
1779          len = this.rbcSource.read (bb);
1780          this.needInput = false;
1781          if (len < 0)
1782            {
1783              return;
1784            }
1785          if (this.charsetName != null)
1786            {
1787              tmpStr = new String (bb.array (), 0, len, this.charsetName);
1788            }
1789          else
1790            {
1791              tmpStr = new String (bb.array (), 0, len);
1792            }
1793          this.actBuffer += tmpStr;
1794        }
1795        catch (IOException e)
1796        {
1797          this.lastIOException = e;
1798        }
1799      }
1800
1801    this.myMatcher.reset (this.actBuffer);
1802  }
1803
1804  /**
1805   * A loop in which the {@link #myFillBuffer()} is called and checked
1806   * if the pattern is found in the matcher and if the buffersize
1807   * changes after the read.
1808   * 
1809   * @param aktM
1810   *            The current Matcher.
1811   * @param pos
1812   *            Position from which the matcher should start matching.
1813   * @param found
1814   *            if already found.
1815   * @return <code> true </code> if the matcher has found a match.
1816   */
1817  private boolean myFillBuffer_loop (final Matcher aktM, final int pos,
1818                                     boolean found)
1819  {
1820    int tmp;
1821
1822    tmp = this.actBuffer.length ();
1823    while (aktM.hitEnd ()
1824           && ((this.bIS != null) || (this.readableSource != null)
1825               || (this.rbcSource != null)))
1826      {
1827        myFillBuffer ();
1828        if (tmp == this.actBuffer.length ())
1829          {
1830            break;
1831          }
1832        found = aktM.find (pos);
1833        this.needInput = true;
1834      }
1835    return found;
1836  }
1837
1838  /**
1839   * Used to find the given pattern in the given string before the
1840   * given horizon. Therfore the current matcher is copied, and
1841   * overwritten using the given pattern and the given Sting. <br>
1842   * After the search the original values are restored, and skipped is
1843   * set <code> true </code>.
1844   * 
1845   * @param pattern
1846   *            Pattern which should be matched.
1847   * @param str
1848   *            The String in which the pattern should be matched.
1849   * @param horizon
1850   *            the horizon whithin the match should be, if 0 then it is ignored.
1851   * @return Returns the String in the given String that matches the pattern.
1852   */
1853  private String myFindPInStr (final Pattern pattern, final String str,
1854                               final int horizon)
1855  {
1856    String rc = null;
1857    int curPos = this.actPos;
1858    Matcher aktMatcher = this.myMatcher;
1859
1860    this.myMatcher = pattern.matcher (str);
1861    if (horizon > 0)
1862      {
1863        this.myMatcher.useAnchoringBounds (true);
1864        this.myMatcher.useTransparentBounds (true);
1865        this.myMatcher.region (this.actPos, this.actPos + horizon);
1866      }
1867    rc = myCoreNext (true, pattern);
1868    this.myMatcher = aktMatcher;
1869
1870    this.actPos = curPos;
1871    this.skipped = true;
1872
1873    return rc;
1874  }
1875
1876  /**
1877   * Used by the {@link #hasNext(Pattern)} and {@link #next(Pattern)}
1878   * methods. Therfore a substring is taken first to the current
1879   * delimiter, afterwards the given pattern is searched in this
1880   * subsring.<br> Finally the current Buffer and matcher (which have
1881   * been temporarily changed) are set back.<br> <br> The {@link
1882   * #skipped} is set <code> true </code>.
1883   * 
1884   * @param pattern
1885   *            Pattern to find until the current delimiter.
1886   * @param delete
1887   *            Is <code> true </code> if a next method is called.<br>
1888   *            Is <code> false </code> if a hasNext method is called.
1889   * @return Returns the String which is returned by the public methods.
1890   */
1891  private String myNext (final Pattern pattern, final boolean delete)
1892  {
1893    String tmpStr;
1894    Matcher aktMatcher = this.myMatcher;
1895    String result;
1896    String currBuffer = this.actBuffer;
1897    int currAktPos;
1898
1899    tmpStr = myCoreNext (delete, this.p);
1900    this.myMatcher = pattern.matcher (tmpStr);
1901    this.actBuffer = tmpStr;
1902    currAktPos = this.actPos;
1903    this.actPos = 0;
1904    result = myCoreNext (delete, pattern);
1905    this.actPos = currAktPos;
1906
1907    this.actBuffer = currBuffer;
1908    this.myMatcher = aktMatcher;
1909    this.skipped = true;
1910
1911    return result;
1912  }
1913
1914  /**
1915   * Calls the next() method internally to get the next String, and
1916   * trys to apply a locale which is only applied if the radix is 10
1917   * and useLocale is <code> true </code>. Afterwards it is tried to
1918   * call the Constructor of a {@link BigInteger} with the given
1919   * radix.
1920   * 
1921   * @param radix The radix to use.
1922   * @param delete If the found String should be removed from input or
1923   * not.
1924   * @param name name of "BigInteger" in case of an Error.
1925   * @return Returns the new BigInteger created if there is no Error.
1926   * @throws InputMismatchException
1927   *             If there is a {@link ParseException} or a {@link NumberFormatException}.
1928   */
1929  private BigInteger myNextBigInteger (final int radix, final boolean delete,
1930                                       final String name)
1931  {
1932    BigInteger rc;
1933    String tmp = myPrepareForNext (this.p, delete);
1934
1935    try
1936    {
1937      tmp = myApplyLocale (tmp, radix);
1938      rc = new BigInteger (tmp, radix);
1939      return rc;
1940    }
1941    catch (NumberFormatException nfe)
1942    {
1943    }
1944    catch (ParseException e)
1945    {
1946    }
1947    throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT + name);
1948  }
1949
1950  /**
1951   * Checks if the next String is either "true" or "false", otherwise
1952   * an {@link InputMismatchException} is thrown. It ignores the case
1953   * of the string so that "true" and "TRUE" and even "TrUe" are
1954   * accepted.
1955   * 
1956   * @param delete Should the found value be removed from the input or
1957   * not.
1958   * @return Returns the boolean value (if it is a boolean).
1959   * @throws InputMismatchException
1960   *             If the next String is not a boolean.
1961   */
1962  private boolean myNextBoolean (final boolean delete) throws
1963    InputMismatchException
1964  {
1965    String tmp = myPrepareForNext (this.p, delete);
1966    if (tmp.equalsIgnoreCase ("true"))
1967      {
1968        return true;
1969      }
1970    else if (tmp.equalsIgnoreCase ("false"))
1971      {
1972        return false;
1973      }
1974    else
1975      {
1976        throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BOOLEAN);
1977      }
1978  }
1979
1980  /**
1981   * Calls the {@link #myPrepareForNext(Pattern, boolean)} which calls
1982   * the {@link #myCoreNext(boolean, Pattern)} to return the next
1983   * String matching the current delimier. Afterwards it is tryed to
1984   * convert the String into a byte. Any Error will lead into a {@link
1985   * InputMismatchException}.
1986   * 
1987   * @param radix The radix to use.
1988   * @param delete Should the found String be removed from the input.
1989   * @return Returns the byte value of the String.
1990   * @throws InputMismatchException if the next String is not a byte.
1991   */
1992  private byte myNextByte (final int radix,
1993                           final boolean delete) throws InputMismatchException
1994  {
1995    byte rc;
1996    String tmp = myPrepareForNext (this.p, delete);
1997
1998      try
1999    {
2000      tmp = myApplyLocale (tmp, radix);
2001      rc = Byte.parseByte (tmp, radix);
2002      return rc;
2003    }
2004    catch (NumberFormatException nfe)
2005    {
2006    }
2007    catch (ParseException e)
2008    {
2009    }
2010    throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BYTE);
2011  }
2012
2013  /**
2014   * Tries to interpret the next String as a double value. To verify
2015   * if the double value is correct, it is converted back to a String
2016   * using the default Locale and this String is compared with the
2017   * String from which the double was converted. If the two Strings
2018   * don't match, an {@link InputMismatchException} is thrown.<br>
2019   * <br> The radix used is always 10 even if the global radix is
2020   * changed.
2021   * 
2022   * @param delete Should the String be removed, if true it will be
2023   * also removed if the String is not a double value.
2024   * @return Returns the double value of the next String.
2025   * @throws InputMismatchException if the next String is not a
2026   * double.
2027   */
2028  private double myNextDouble (final boolean delete) throws
2029    InputMismatchException
2030  {
2031    double rc;
2032    String tmp = myPrepareForNext (this.p, delete);
2033
2034      try
2035    {
2036      tmp = myApplyLocale (tmp, 10);
2037      rc = Double.parseDouble (tmp);
2038      if (("" + rc).equals (tmp))
2039        {
2040          return rc;
2041        }
2042    }
2043    catch (ParseException e)
2044    {
2045    }
2046    throw new InputMismatchException (ERR_PREFIX + tmp + NOT_DOUBLE);
2047  }
2048
2049  /**
2050   * Tries to interpret the next String as an int value. Therfore
2051   * {@link #myApplyLocale(String, int)} decides if the current Locale
2052   * should be applied or not and then the result is parsed using
2053   * {@link Integer#parseInt(String, int)}. Any Error will lead to an
2054   * {@link InputMismatchException}.
2055   * 
2056   * @param radix The radix to use.
2057   * @param delete <code> true </code> if the String should be deleted
2058   * from the input.
2059   * @return Returns the int value of the String.
2060   * @throws InputMismatchException if the next String is not an int.
2061   */
2062  private int myNextInt (final int radix,
2063                         final boolean delete) throws InputMismatchException
2064  {
2065    int rc;
2066    String tmp = myPrepareForNext (this.p, delete);
2067    try
2068      {
2069        tmp = myApplyLocale (tmp, radix);
2070        rc = Integer.parseInt (tmp, radix);
2071        return rc;
2072      }
2073    catch (NumberFormatException nfe)
2074    {
2075    }
2076    catch (ParseException e)
2077    {
2078    }
2079    throw new InputMismatchException (ERR_PREFIX + tmp + NOT_INT);
2080  }
2081
2082  /**
2083   * Finds the next line using the {@link #NEW_LINE} constant which is
2084   * set to the system specific line seperator.
2085   * 
2086   * @param delete Should the found line be deleted from the input.
2087   * @return Returns the current line.
2088   */
2089  private String myNextLine (final boolean delete)
2090  {
2091    String rc = null;
2092    rc = myPrepareForNext (Pattern.compile (NEW_LINE), delete);
2093    return rc;
2094  }
2095
2096  /**
2097   * Tries to interpret the next String as a long value with the given
2098   * radix. Therfore the {@link Long#parseLong(String, int)} is called
2099   * and every Error will lead into a {@link InputMismatchException}.
2100   * 
2101   * @param radix The radix to be used.
2102   * @param delete Should the found String be deleted from the input.
2103   * @return the long value of the next String.
2104   * @throws InputMismatchException if the next String is not a long.
2105   */
2106  private long myNextLong (final int radix,
2107                           final boolean delete) throws InputMismatchException
2108  {
2109    long rc;
2110    String tmp = myPrepareForNext (this.p, delete);
2111
2112    try
2113      {
2114        tmp = myApplyLocale (tmp, radix);
2115        rc = Long.parseLong (tmp, radix);
2116        return rc;
2117      }
2118    catch (NumberFormatException nfe)
2119      {
2120      }
2121    catch (ParseException e)
2122      {
2123      }
2124    throw new InputMismatchException (ERR_PREFIX + tmp + NOT_LONG);
2125  }
2126
2127  /**
2128   * Tries to interpret the next String as a short value with the
2129   * given radix. Therfore the {@link Short#parseShort(String, int)}
2130   * is called and every Error will lead into a {@link
2131   * InputMismatchException} .
2132   * 
2133   * @param radix
2134   *            The radix to be used.
2135   * @param delete
2136   *            Should the found String be deleted from the input.
2137   * @return the long value of the next String.
2138   * @throws InputMismatchException
2139   *             if the next String is not a short.
2140   */
2141  private short myNextShort (final int radix,
2142                             final boolean delete) throws
2143    InputMismatchException
2144  {
2145    short rc;
2146    String tmp = myPrepareForNext (this.p, delete);
2147    
2148    try
2149      {
2150        tmp = myApplyLocale (tmp, radix);
2151        rc = Short.parseShort (tmp, radix);
2152        return rc;
2153      }
2154    catch (NumberFormatException nfe)
2155      {
2156      }
2157    catch (ParseException e)
2158      {
2159      }
2160    throw new InputMismatchException (ERR_PREFIX + tmp +
2161                                      "\" is not a short");
2162  }
2163
2164  /**
2165   * Sets the current pattern to the given pattern and calls the
2166   * {@link #myCoreNext(boolean, Pattern)}. Finally sets the pattern
2167   * back to its old value.
2168   * 
2169   * @param aktPattern Pattern to be used for the next match.
2170   * @param delete Should the found String be deleted or not.
2171   * @return Return the String returned from {@link
2172   * #myCoreNext(boolean, Pattern)}.
2173   */
2174  private String myPrepareForNext (final Pattern aktPattern,
2175                                   final boolean delete)
2176  {
2177
2178    String rc;
2179    Pattern oldPattern = this.p;
2180    useDelimiter (aktPattern);
2181
2182    rc = myCoreNext (delete, aktPattern);
2183
2184    useDelimiter (oldPattern);
2185
2186    return rc;
2187  }
2188
2189  /**
2190   * Determinates if the last found can be used, so that after a
2191   * hasNextXXX the nextXXX has not to search if nothing has
2192   * changed.<br /> Used in {@link #myCoreNext(boolean, Pattern)}.
2193   * 
2194   * @param aktP The pattern which should be checked.
2195   * @return <code> true </code> if the searchresult is already ready.
2196   */
2197  private boolean shallUseLastFound (final Pattern aktP)
2198  {
2199    if (this.lastFoundPresent &&
2200        this.lastPatternHash == aktP.hashCode () &&
2201        this.last_RegionStart == this.myMatcher.regionStart () &&
2202        this.last_anchor == this.myMatcher.hasAnchoringBounds () &&
2203        this.last_transparent == this.myMatcher.hasTransparentBounds ())
2204      {
2205        if (this.last_RegionEnd != this.myMatcher.regionEnd ())
2206          {
2207            int tmpVal =
2208              this.myMatcher.regionEnd () -
2209              this.last_RegionEnd - this.MAX_PREFIX;
2210            if (tmpVal > 0 && tmpVal < 20)
2211              {
2212                this.last_RegionEnd =
2213                  this.myMatcher.regionEnd ();
2214                return true;
2215              }
2216          }
2217        else
2218          return true;
2219      }
2220    return false;
2221  }
2222
2223}