1 /* java.util.Scanner -- Parses primitive types and strings using regexps
2    Copyright (C) 2007  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package java.util;
39 
40 import java.io.BufferedInputStream;
41 import java.io.File;
42 import java.io.FileInputStream;
43 import java.io.FileNotFoundException;
44 import java.io.IOException;
45 import java.io.InputStream;
46 
47 import java.math.BigDecimal;
48 import java.math.BigInteger;
49 
50 import java.nio.ByteBuffer;
51 import java.nio.CharBuffer;
52 import java.nio.channels.ReadableByteChannel;
53 
54 import java.text.DecimalFormat;
55 import java.text.DecimalFormatSymbols;
56 import java.text.NumberFormat;
57 import java.text.ParseException;
58 
59 import java.util.Iterator;
60 import java.util.Locale;
61 import java.util.regex.MatchResult;
62 import java.util.regex.Matcher;
63 import java.util.regex.Pattern;
64 
65 /**
66  * @author E0327023 Hernadi Laszlo
67 */
68 public class Scanner
69   implements Iterator <String>
70 {
71   private static final String NOT_LONG = "\" is not a long";    //$NON-NLS-1$
72 
73   private static final String ERR_PREFIX = "\"";        //$NON-NLS-1$
74 
75   private static final String NOT_INT = "\" is not an integer"; //$NON-NLS-1$
76 
77   private static final String NOT_DOUBLE = "\" is not a double";        //$NON-NLS-1$
78 
79   private static final String NOT_BYTE = "\" is not a byte";    //$NON-NLS-1$
80 
81   private static final String NOT_BOOLEAN = "\" is not a boolean";      //$NON-NLS-1$
82 
83   private static final String IS_NOT = "\" is not ";    //$NON-NLS-1$
84 
85   private static final String DEFAULT_PATTERN_S = "\\p{javaWhitespace}+";       //$NON-NLS-1$
86 
87   private static final Pattern DEFAULT_PATTERN =
88     Pattern.compile (DEFAULT_PATTERN_S);
89 
90   private static final String BIG_INTEGER = "BigInteger";       //$NON-NLS-1$
91 
92   private final static String NEW_LINE =
93     System.getProperty ("line.separator");
94 
95   private IOException lastIOException = null;
96 
97   /**
98    * An InputStream source if a Constructor with an InputStream source is called, otherwise it
99    * 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    */
Scanner(final File source)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    */
Scanner(final File source, final String charsetName)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    */
Scanner(final InputStream source)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    */
Scanner(final InputStream source, final String charsetName)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    */
Scanner(final Readable source)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    */
Scanner(final ReadableByteChannel source)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    */
Scanner(final ReadableByteChannel source, final String charsetName)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    */
Scanner(final String source)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    */
close()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    */
delimiter()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    */
findInLine(final Pattern pattern)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    */
findInLine(final String pattern)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    */
findWithinHorizon(final Pattern pattern, final int horizon)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    */
findWithinHorizon(final String pattern, final int horizon)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    */
hasNext()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    */
hasNext(final Pattern pattern)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    */
hasNext(final String pattern)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    */
hasNextBigDecimal()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    */
hasNextBigInteger()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    */
hasNextBigInteger(final int radix)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    */
hasNextBoolean()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    */
hasNextByte()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    */
hasNextByte(final int radix)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    */
hasNextDouble()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    */
hasNextFloat()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    */
hasNextInt()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    */
hasNextInt(final int radix)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    */
hasNextLine()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    */
hasNextLong()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    */
hasNextLong(final int radix)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    */
hasNextShort()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    */
hasNextShort(final int radix)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    */
ioException()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    */
isUseLocale()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    */
locale()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    */
match()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    */
next()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    */
next(final Pattern pattern)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    */
next(final String pattern)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    */
nextBigDecimal()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    */
nextBigInteger()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    */
nextBigInteger(final int radix)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    */
nextBoolean()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    */
nextByte()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    */
nextByte(final int radix)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    */
nextDouble()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    */
nextFloat()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    */
nextInt()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    */
nextInt(final int radix)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    */
nextLine()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    */
nextLong()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    */
nextLong(final int radix)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    */
nextShort()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    */
nextShort(final int radix)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    */
radix()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    */
remove()1230   public void remove ()
1231   {
1232   }
1233 
1234   /**
1235    * @param useLocale the useLocale to set.
1236    */
setUseLocale(final boolean useLocale)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    */
skip(final Pattern pattern)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    */
skip(final String pattern)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
toString()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    */
useDelimiter(final Pattern pattern)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    */
useDelimiter(final String pattern)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    */
useLocale(final Locale locale)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    */
useRadix(final int radix)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    */
myApplyLocale(final String str, final int radix)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    */
myApplyLocaleBD(final String str)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    */
myBigDecimal(final boolean delete)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    */
myConvert(final String str)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    */
myCoreNext(final boolean delete, final Pattern pattern)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         if (tmp2.length() == 0)
1672           tmp2 = null;
1673         this.lastNextPos = this.actBuffer.length ();
1674         if (delete)
1675           {
1676             this.actPos = this.lastNextPos;
1677           }
1678         else
1679           {
1680             this.lastFound = tmp2;
1681             this.lastFoundPresent = true;
1682             this.lastPatternHash = pattern.hashCode ();
1683           }
1684         this.last_RegionStart = this.myMatcher.regionStart ();
1685         this.last_RegionEnd = this.myMatcher.regionEnd ();
1686         this.last_anchor = this.myMatcher.hasAnchoringBounds ();
1687         this.last_transparent = this.myMatcher.hasTransparentBounds ();
1688       }
1689     else
1690       {
1691         /*
1692          * if no match found an Exception is throwed
1693          */
1694         throw new NoSuchElementException ();
1695       }
1696     /*
1697      * change the Result only when a nextXXX() method was called, not if a hasNextXXX() method
1698      * is called
1699      */
1700     if (delete)
1701       {
1702         this.actResult = this.myMatcher.toMatchResult ();
1703 
1704         this.matchValid = this.actResult != null;
1705       }
1706     else
1707       {
1708         this.lastResult = this.myMatcher.toMatchResult ();
1709       }
1710 
1711     this.skipped = this.doSkipp;
1712     this.doSkipp = false;
1713 
1714     return tmp2;
1715   }
1716 
1717   /**
1718    * Used to fill the String buffer from a source. Therfore the 3
1719    * possible sources are checked if they are not <code>null</code>
1720    * and this not used, otherwise the read method is called on the
1721    * source. If a charsetName is set and not <code>null</code> it is
1722    * applied to convert to String.
1723    */
myFillBuffer()1724   private void myFillBuffer ()
1725   {
1726     int len;
1727     String tmpStr;
1728     CharBuffer cb = null;
1729     ByteBuffer bb = null;
1730 
1731     if (this.bIS != null)
1732       {
1733         try
1734         {
1735           len = this.bIS.read (this.tmpBuffer);
1736           if (len < 0)
1737             {
1738               return;
1739             }
1740           if (this.charsetName != null)
1741             {
1742               tmpStr = new String (this.tmpBuffer, 0, len, this.charsetName);
1743             }
1744           else
1745             {
1746               tmpStr = new String (this.tmpBuffer, 0, len);
1747             }
1748           this.actBuffer += tmpStr;
1749         }
1750         catch (IOException e)
1751         {
1752           this.lastIOException = e;
1753         }
1754       }
1755     else if (this.readableSource != null)
1756       {
1757         try
1758         {
1759           cb = CharBuffer.allocate (1000);
1760           this.needInput = true;
1761           len = this.readableSource.read (cb);
1762           if (len < 0)
1763             {
1764               return;
1765             }
1766           this.needInput = false;
1767           tmpStr = new String (cb.array ());
1768           this.actBuffer += tmpStr;
1769         }
1770         catch (IOException e)
1771         {
1772           this.lastIOException = e;
1773         }
1774       }
1775     else if (this.rbcSource != null)
1776       {
1777         try
1778         {
1779           bb = ByteBuffer.allocate (1000);
1780           this.needInput = true;
1781           len = this.rbcSource.read (bb);
1782           this.needInput = false;
1783           if (len < 0)
1784             {
1785               return;
1786             }
1787           if (this.charsetName != null)
1788             {
1789               tmpStr = new String (bb.array (), 0, len, this.charsetName);
1790             }
1791           else
1792             {
1793               tmpStr = new String (bb.array (), 0, len);
1794             }
1795           this.actBuffer += tmpStr;
1796         }
1797         catch (IOException e)
1798         {
1799           this.lastIOException = e;
1800         }
1801       }
1802 
1803     this.myMatcher.reset (this.actBuffer);
1804   }
1805 
1806   /**
1807    * A loop in which the {@link #myFillBuffer()} is called and checked
1808    * if the pattern is found in the matcher and if the buffersize
1809    * changes after the read.
1810    *
1811    * @param aktM
1812    *            The current Matcher.
1813    * @param pos
1814    *            Position from which the matcher should start matching.
1815    * @param found
1816    *            if already found.
1817    * @return <code> true </code> if the matcher has found a match.
1818    */
myFillBuffer_loop(final Matcher aktM, final int pos, boolean found)1819   private boolean myFillBuffer_loop (final Matcher aktM, final int pos,
1820                                      boolean found)
1821   {
1822     int tmp;
1823 
1824     tmp = this.actBuffer.length ();
1825     while (aktM.hitEnd ()
1826            && ((this.bIS != null) || (this.readableSource != null)
1827                || (this.rbcSource != null)))
1828       {
1829         myFillBuffer ();
1830         if (tmp == this.actBuffer.length ())
1831           {
1832             break;
1833           }
1834         found = aktM.find (pos);
1835         this.needInput = true;
1836       }
1837     return found;
1838   }
1839 
1840   /**
1841    * Used to find the given pattern in the given string before the
1842    * given horizon. Therfore the current matcher is copied, and
1843    * overwritten using the given pattern and the given Sting. <br>
1844    * After the search the original values are restored, and skipped is
1845    * set <code> true </code>.
1846    *
1847    * @param pattern
1848    *            Pattern which should be matched.
1849    * @param str
1850    *            The String in which the pattern should be matched.
1851    * @param horizon
1852    *            the horizon whithin the match should be, if 0 then it is ignored.
1853    * @return Returns the String in the given String that matches the pattern.
1854    */
myFindPInStr(final Pattern pattern, final String str, final int horizon)1855   private String myFindPInStr (final Pattern pattern, final String str,
1856                                final int horizon)
1857   {
1858     String rc = null;
1859     int curPos = this.actPos;
1860     Matcher aktMatcher = this.myMatcher;
1861 
1862     this.myMatcher = pattern.matcher (str);
1863     if (horizon > 0)
1864       {
1865         this.myMatcher.useAnchoringBounds (true);
1866         this.myMatcher.useTransparentBounds (true);
1867         this.myMatcher.region (this.actPos, this.actPos + horizon);
1868       }
1869     rc = myCoreNext (true, pattern);
1870     this.myMatcher = aktMatcher;
1871 
1872     this.actPos = curPos;
1873     this.skipped = true;
1874 
1875     return rc;
1876   }
1877 
1878   /**
1879    * Used by the {@link #hasNext(Pattern)} and {@link #next(Pattern)}
1880    * methods. Therfore a substring is taken first to the current
1881    * delimiter, afterwards the given pattern is searched in this
1882    * subsring.<br> Finally the current Buffer and matcher (which have
1883    * been temporarily changed) are set back.<br> <br> The {@link
1884    * #skipped} is set <code> true </code>.
1885    *
1886    * @param pattern
1887    *            Pattern to find until the current delimiter.
1888    * @param delete
1889    *            Is <code> true </code> if a next method is called.<br>
1890    *            Is <code> false </code> if a hasNext method is called.
1891    * @return Returns the String which is returned by the public methods.
1892    */
myNext(final Pattern pattern, final boolean delete)1893   private String myNext (final Pattern pattern, final boolean delete)
1894   {
1895     String tmpStr;
1896     Matcher aktMatcher = this.myMatcher;
1897     String result;
1898     String currBuffer = this.actBuffer;
1899     int currAktPos;
1900 
1901     tmpStr = myCoreNext (delete, this.p);
1902     this.myMatcher = pattern.matcher (tmpStr);
1903     this.actBuffer = tmpStr;
1904     currAktPos = this.actPos;
1905     this.actPos = 0;
1906     result = myCoreNext (delete, pattern);
1907     this.actPos = currAktPos;
1908 
1909     this.actBuffer = currBuffer;
1910     this.myMatcher = aktMatcher;
1911     this.skipped = true;
1912 
1913     return result;
1914   }
1915 
1916   /**
1917    * Calls the next() method internally to get the next String, and
1918    * trys to apply a locale which is only applied if the radix is 10
1919    * and useLocale is <code> true </code>. Afterwards it is tried to
1920    * call the Constructor of a {@link BigInteger} with the given
1921    * radix.
1922    *
1923    * @param radix The radix to use.
1924    * @param delete If the found String should be removed from input or
1925    * not.
1926    * @param name name of "BigInteger" in case of an Error.
1927    * @return Returns the new BigInteger created if there is no Error.
1928    * @throws InputMismatchException
1929    *             If there is a {@link ParseException} or a {@link NumberFormatException}.
1930    */
myNextBigInteger(final int radix, final boolean delete, final String name)1931   private BigInteger myNextBigInteger (final int radix, final boolean delete,
1932                                        final String name)
1933   {
1934     BigInteger rc;
1935     String tmp = myPrepareForNext (this.p, delete);
1936 
1937     try
1938     {
1939       tmp = myApplyLocale (tmp, radix);
1940       rc = new BigInteger (tmp, radix);
1941       return rc;
1942     }
1943     catch (NumberFormatException nfe)
1944     {
1945     }
1946     catch (ParseException e)
1947     {
1948     }
1949     throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT + name);
1950   }
1951 
1952   /**
1953    * Checks if the next String is either "true" or "false", otherwise
1954    * an {@link InputMismatchException} is thrown. It ignores the case
1955    * of the string so that "true" and "TRUE" and even "TrUe" are
1956    * accepted.
1957    *
1958    * @param delete Should the found value be removed from the input or
1959    * not.
1960    * @return Returns the boolean value (if it is a boolean).
1961    * @throws InputMismatchException
1962    *             If the next String is not a boolean.
1963    */
myNextBoolean(final boolean delete)1964   private boolean myNextBoolean (final boolean delete) throws
1965     InputMismatchException
1966   {
1967     String tmp = myPrepareForNext (this.p, delete);
1968     if (tmp.equalsIgnoreCase ("true"))
1969       {
1970         return true;
1971       }
1972     else if (tmp.equalsIgnoreCase ("false"))
1973       {
1974         return false;
1975       }
1976     else
1977       {
1978         throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BOOLEAN);
1979       }
1980   }
1981 
1982   /**
1983    * Calls the {@link #myPrepareForNext(Pattern, boolean)} which calls
1984    * the {@link #myCoreNext(boolean, Pattern)} to return the next
1985    * String matching the current delimier. Afterwards it is tryed to
1986    * convert the String into a byte. Any Error will lead into a {@link
1987    * InputMismatchException}.
1988    *
1989    * @param radix The radix to use.
1990    * @param delete Should the found String be removed from the input.
1991    * @return Returns the byte value of the String.
1992    * @throws InputMismatchException if the next String is not a byte.
1993    */
myNextByte(final int radix, final boolean delete)1994   private byte myNextByte (final int radix,
1995                            final boolean delete) throws InputMismatchException
1996   {
1997     byte rc;
1998     String tmp = myPrepareForNext (this.p, delete);
1999 
2000       try
2001     {
2002       tmp = myApplyLocale (tmp, radix);
2003       rc = Byte.parseByte (tmp, radix);
2004       return rc;
2005     }
2006     catch (NumberFormatException nfe)
2007     {
2008     }
2009     catch (ParseException e)
2010     {
2011     }
2012     throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BYTE);
2013   }
2014 
2015   /**
2016    * Tries to interpret the next String as a double value. To verify
2017    * if the double value is correct, it is converted back to a String
2018    * using the default Locale and this String is compared with the
2019    * String from which the double was converted. If the two Strings
2020    * don't match, an {@link InputMismatchException} is thrown.<br>
2021    * <br> The radix used is always 10 even if the global radix is
2022    * changed.
2023    *
2024    * @param delete Should the String be removed, if true it will be
2025    * also removed if the String is not a double value.
2026    * @return Returns the double value of the next String.
2027    * @throws InputMismatchException if the next String is not a
2028    * double.
2029    */
myNextDouble(final boolean delete)2030   private double myNextDouble (final boolean delete) throws
2031     InputMismatchException
2032   {
2033     double rc;
2034     String tmp = myPrepareForNext (this.p, delete);
2035 
2036       try
2037     {
2038       tmp = myApplyLocale (tmp, 10);
2039       rc = Double.parseDouble (tmp);
2040       if (("" + rc).equals (tmp))
2041         {
2042           return rc;
2043         }
2044     }
2045     catch (ParseException e)
2046     {
2047     }
2048     throw new InputMismatchException (ERR_PREFIX + tmp + NOT_DOUBLE);
2049   }
2050 
2051   /**
2052    * Tries to interpret the next String as an int value. Therfore
2053    * {@link #myApplyLocale(String, int)} decides if the current Locale
2054    * should be applied or not and then the result is parsed using
2055    * {@link Integer#parseInt(String, int)}. Any Error will lead to an
2056    * {@link InputMismatchException}.
2057    *
2058    * @param radix The radix to use.
2059    * @param delete <code> true </code> if the String should be deleted
2060    * from the input.
2061    * @return Returns the int value of the String.
2062    * @throws InputMismatchException if the next String is not an int.
2063    */
myNextInt(final int radix, final boolean delete)2064   private int myNextInt (final int radix,
2065                          final boolean delete) throws InputMismatchException
2066   {
2067     int rc;
2068     String tmp = myPrepareForNext (this.p, delete);
2069     try
2070       {
2071         tmp = myApplyLocale (tmp, radix);
2072         rc = Integer.parseInt (tmp, radix);
2073         return rc;
2074       }
2075     catch (NumberFormatException nfe)
2076     {
2077     }
2078     catch (ParseException e)
2079     {
2080     }
2081     throw new InputMismatchException (ERR_PREFIX + tmp + NOT_INT);
2082   }
2083 
2084   /**
2085    * Finds the next line using the {@link #NEW_LINE} constant which is
2086    * set to the system specific line seperator.
2087    *
2088    * @param delete should the found line be deleted from the input.
2089    * @return the current line.
2090    */
myNextLine(final boolean delete)2091   private String myNextLine (final boolean delete)
2092   {
2093     return myPrepareForNext (Pattern.compile (NEW_LINE), delete);
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    */
myNextLong(final int radix, final boolean delete)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    */
myNextShort(final int radix, final boolean delete)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    */
myPrepareForNext(final Pattern aktPattern, final boolean delete)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    */
shallUseLastFound(final Pattern aktP)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 }
2224