001    /* java.util.Scanner -- Parses primitive types and strings using regexps
002       Copyright (C) 2007  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package java.util;
039    
040    import java.io.BufferedInputStream;
041    import java.io.File;
042    import java.io.FileInputStream;
043    import java.io.FileNotFoundException;
044    import java.io.IOException;
045    import java.io.InputStream;
046    
047    import java.math.BigDecimal;
048    import java.math.BigInteger;
049    
050    import java.nio.ByteBuffer;
051    import java.nio.CharBuffer;
052    import java.nio.channels.ReadableByteChannel;
053    
054    import java.text.DecimalFormat;
055    import java.text.DecimalFormatSymbols;
056    import java.text.NumberFormat;
057    import java.text.ParseException;
058    
059    import java.util.Iterator;
060    import java.util.Locale;
061    import java.util.regex.MatchResult;
062    import java.util.regex.Matcher;
063    import java.util.regex.Pattern;
064    
065    /**
066     * @author E0327023 Hernadi Laszlo
067     */
068    public 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    }