Advertisement
Guest User

Scanner.java

a guest
Feb 27th, 2015
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 27.23 KB | None | 0 0
  1. import java.io.*;
  2. import java.math.*;
  3. import java.util.*;
  4.  
  5. /**
  6. A simple text scanner which can parse primitive types and strings
  7. using regular expressions.
  8.  
  9. <p>
  10. A Scanner breaks its input into tokens using a delimiter pattern,
  11. which by default matches whitespace. The resulting tokens may then be
  12. converted into values of different types using the various next methods.
  13.  
  14. <p>
  15. This class is based on a subset of the functionality of Sun's
  16. java.util.Scanner class from J2SE v1.5.0 RC1, with some code borrowed
  17. from the TextReader class written by Stuart Reges of the
  18. University of Washington.  It should work with 'lazy input' from the
  19. keyboard as needed.
  20.  
  21. <p>
  22. This implementation does not include the static factory
  23. Scanner.create methods as included in J2SE 1.5.0 beta 1.
  24.  
  25. <p>
  26. Some notable differences from java.util.Scanner are the following:
  27.  
  28. <ul><li>
  29.  
  30. All Java 5-specific features, such as implementing Iterator &lt; String &gt; ,
  31. are missing.
  32.  
  33. </li><li>
  34.  
  35. All support for regular expressions (Pattern, Matcher, MatchResult),
  36. changing locales, and specalized character sets is missing.
  37.  
  38. </li><li>
  39.  
  40. This implementation is not guaranteed to exactly match the parsing behavior
  41. of java.util.Scanner for complex cases.  The java.util.Scanner uses
  42. sophisticated delimiting between tokens of input; this Scanner simply
  43. tokenizes on whitespace.  Also, for example, this implementation returns
  44. true on a call to hasNextFloat() if the upcoming input token is "2.1F",
  45. because this implementation's parsing is based on the primitive wrappers;
  46. java.util.Scanner would return false in this same case.
  47.  
  48. </li><li>
  49.  
  50. The toString text, exception text and exception-throwing behavior
  51. is not guaranteed to match that of java.util.Scanner.  In particular,
  52. this implementation includes the offending input line number in its
  53. NoSuchElementException text to aid debugging.
  54.  
  55. </li><li>
  56.  
  57. This implementation is slower than java.util.Scanner, partly because it
  58. does not directly cache input for simplicity.  Since this class is a
  59. holdover implementation until widespread adoption of Java 5, this was
  60. deemed acceptable.
  61.  
  62. </li></ul>
  63.  
  64. <p>
  65. Recent changes:
  66.  
  67. <ul><li>
  68.  
  69. 2005-01-01: Renamed all private methods with underscores because students
  70. were discovering the private hasNextChar method and trying to use it in
  71. their programs.
  72.  
  73. </li><li>
  74.  
  75. 2005-01-22: Fixed a bug where nextLine returned an empty string rather than
  76. throwing an exception when no more input was available.
  77.  
  78. </li></ul>
  79.  
  80. @author Marty Stepp (stepp AT u washington edu),
  81. Lecturer, University of Washington-Tacoma Institute of Technology
  82.  
  83. @version January 22, 2005
  84. */
  85. public final class Scanner {
  86.   private static final int EOF = -1;           // used to denote end-of-input
  87.   private static final int PUSHBACK_BUFFER_SIZE = 4096;  // buffer to unread
  88.   private static final String DELIMITER = " \t\f\r\n";   // whitespace chars
  89.   private static final String TRUE = "true";
  90.   private static final String FALSE = "false";
  91.   private static final String REMOVE_EXCEPTION_MESSAGE =
  92.     "Remove is not supported by this Scanner.";
  93.   private static final String BAD_INPUT_EXCEPTION_MESSAGE =
  94.     "bad input, line ";
  95.  
  96.   private PushbackReader m_reader;           // underlying input source
  97.   private LineNumberReader m_lnReader;       // keeps track of line numbers
  98.   private IOException m_ioException = null;  // last IO exception
  99.   private StringBuffer m_previousNextBuffer = new StringBuffer();
  100.   private int m_radix = 10;                  // default integer base
  101.   private boolean m_closed = false;          // set true on close or exception
  102.  
  103.   /**
  104.   Constructs a new Scanner that produces values scanned from the specified
  105.   file. Bytes from the file are converted into characters using the
  106.   underlying platform's default charset.
  107.  
  108.   @param source A file to be scanned
  109.   @throws FileNotFoundException if source is not found
  110.   */
  111.   public Scanner(File source) throws FileNotFoundException {
  112.     this(new FileInputStream(source));
  113.   }
  114.  
  115.   /**
  116.   Constructs a new Scanner that produces values scanned from the specified
  117.   input stream. Bytes from the stream are converted into characters using
  118.   the underlying platform's default charset.
  119.  
  120.   @param source An input stream to be scanned
  121.   */
  122.   public Scanner(InputStream source) {
  123.     this(new InputStreamReader(source));
  124.   }
  125.  
  126.   /**
  127.   Constructs a new Scanner that produces values scanned from the specified
  128.   source.
  129.  
  130.   @param source A character source to scan
  131.   */
  132.   public Scanner(Reader source) {
  133.     m_lnReader = new LineNumberReader(source);
  134.     m_lnReader.setLineNumber(1);  // it would be 0-based otherwise
  135.     m_reader = new PushbackReader(m_lnReader, PUSHBACK_BUFFER_SIZE);
  136.   }
  137.  
  138.   /**
  139.   Constructs a new Scanner that produces values scanned from the specified
  140.   string.
  141.  
  142.   @param source A string to scan
  143.   */
  144.   public Scanner(String source) {
  145.     this(new StringReader(source));
  146.   }
  147.  
  148.   /**
  149.   Closes this scanner.
  150.  
  151.   <p>
  152.   If this scanner is already closed then invoking
  153.   this method will have no effect.
  154.   */
  155.   public void close() {
  156.     try {
  157.       m_reader.close();
  158.       m_closed = true;
  159.     } catch (IOException ioe) {
  160.       _setIoException(ioe);
  161.     }
  162.   }
  163.  
  164.   /**
  165.   Returns true if this scanner has another token in its input. This method
  166.   may block while waiting for input to scan. The scanner does not advance
  167.   past any input.
  168.  
  169.   @return true if and only if this scanner has another token
  170.   @throws IllegalStateException if this scanner is closed
  171.   */
  172.   public boolean hasNext() {
  173.     try {
  174.       next();
  175.       return true;
  176.     } catch (NoSuchElementException nsee) {
  177.       return false;
  178.     } finally {
  179.       _undoNext();
  180.     }
  181.   }
  182.  
  183.   /**
  184.   Returns true if the next token in this scanner's input can be interpreted
  185.   as a BigDecimal using the nextBigDecimal() method. The scanner does not
  186.   advance past any input.
  187.  
  188.   @return true if and only if this scanner's next token is a valid BigDecimal
  189.   @throws IllegalStateException if this scanner is closed
  190.   */
  191.   public boolean hasNextBigDecimal() {
  192.     try {
  193.       nextBigDecimal();
  194.       return true;
  195.     } catch (NoSuchElementException nsee) {
  196.       return false;
  197.     } finally {
  198.       _undoNext();
  199.     }
  200.   }
  201.  
  202.   /**
  203.   Returns true if the next token in this scanner's input can be interpreted
  204.   as a BigInteger in the default radix using the nextBigInteger() method.
  205.   The scanner does not advance past any input.
  206.  
  207.   @return true if and only if this scanner's next token is a valid BigInteger
  208.   @throws IllegalStateException if this scanner is closed
  209.   */
  210.   public boolean hasNextBigInteger() {
  211.     return hasNextBigInteger(m_radix);
  212.   }
  213.  
  214.   /**
  215.   Returns true if the next token in this scanner's input can be interpreted as
  216.   a BigInteger in the specified radix using the nextBigInteger() method. The
  217.   scanner does not advance past any input.
  218.  
  219.   @param radix the radix used to interpret the token as an integer
  220.   @return true if and only if this scanner's next token is a valid BigInteger
  221.   @throws IllegalStateException if this scanner is closed
  222.   */
  223.   public boolean hasNextBigInteger(int radix) {
  224.     try {
  225.       nextBigInteger(radix);
  226.       return true;
  227.     } catch (NoSuchElementException nsee) {
  228.       return false;
  229.     } finally {
  230.       _undoNext();
  231.     }
  232.   }
  233.  
  234.   /**
  235.   Returns true if the next token in this scanner's input can be interpreted as
  236.   a boolean value. The scanner does not advance past the input that matched.
  237.  
  238.   @return true if and only if this scanner's next token is a valid boolean value
  239.   @throws IllegalStateException if this scanner is closed
  240.   */
  241.   public boolean hasNextBoolean() {
  242.     try {
  243.       nextBoolean();
  244.       return true;
  245.     } catch (NoSuchElementException nsee) {
  246.       return false;
  247.     } finally {
  248.       _undoNext();
  249.     }
  250.   }
  251.  
  252.   /**
  253.   Returns true if the next token in this scanner's input can be interpreted as
  254.   a byte value in the default radix using the nextByte() method. The scanner
  255.   does not advance past any input.
  256.  
  257.   @return true if and only if this scanner's next token is a valid byte value
  258.   @throws IllegalStateException if this scanner is closed
  259.   */
  260.   public boolean hasNextByte() {
  261.     return hasNextByte(m_radix);
  262.   }
  263.  
  264.   /**
  265.   Returns true if the next token in this scanner's input can be interpreted as
  266.   a byte value in the specified radix using the nextByte() method. The scanner
  267.   does not advance past any input.
  268.  
  269.   @param radix the radix used to interpret the token as a byte value
  270.   @return true if and only if this scanner's next token is a valid byte value
  271.   @throws IllegalStateException if this scanner is closed
  272.   */
  273.   public boolean hasNextByte(int radix) {
  274.     try {
  275.       nextByte(radix);
  276.       return true;
  277.     } catch (NoSuchElementException nsee) {
  278.       return false;
  279.     } finally {
  280.       _undoNext();
  281.     }
  282.   }
  283.  
  284.   /**
  285.   Returns true if the next token in this scanner's input can be interpreted as
  286.   a double value using the nextDouble() method. The scanner does not advance
  287.   past any input.
  288.  
  289.   @return true if and only if this scanner's next token is a valid double value
  290.   @throws IllegalStateException if this scanner is closed
  291.   */
  292.   public boolean hasNextDouble() {
  293.     try {
  294.       nextDouble();
  295.       return true;
  296.     } catch (NoSuchElementException nsee) {
  297.       return false;
  298.     } finally {
  299.       _undoNext();
  300.     }
  301.   }
  302.  
  303.   /**
  304.   Returns true if the next token in this scanner's input can be interpreted as
  305.   a float value using the nextFloat() method. The scanner does not advance past
  306.   any input.
  307.  
  308.   @return true if and only if this scanner's next token is a valid float value
  309.   @throws IllegalStateException if this scanner is closed
  310.   */
  311.   public boolean hasNextFloat() {
  312.     try {
  313.       nextFloat();
  314.       return true;
  315.     } catch (NoSuchElementException nsee) {
  316.       return false;
  317.     } finally {
  318.       _undoNext();
  319.     }
  320.   }
  321.  
  322.   /**
  323.   Returns true if the next token in this scanner's input can be interpreted as
  324.   an int value in the default radix using the nextInt() method. The scanner
  325.   does not advance past any input.
  326.  
  327.   @return true if and only if this scanner's next token is a valid int value
  328.   @throws IllegalStateException if this scanner is closed
  329.   */
  330.   public boolean hasNextInt() {
  331.     return hasNextInt(m_radix);
  332.   }
  333.  
  334.   /**
  335.   Returns true if the next token in this scanner's input can be interpreted as
  336.   an int value in the specified radix using the nextInt() method. The scanner
  337.   does not advance past any input.
  338.  
  339.   @param radix the radix used to interpret the token as an int value
  340.   @return true if and only if this scanner's next token is a valid int value
  341.   @throws IllegalStateException if this scanner is closed
  342.   */
  343.   public boolean hasNextInt(int radix) {
  344.     try {
  345.       nextInt(radix);
  346.       return true;
  347.     } catch (NoSuchElementException nsee) {
  348.       return false;
  349.     } finally {
  350.       _undoNext();
  351.     }
  352.   }
  353.  
  354.   /**
  355.   Returns true if there is another line in the input of this scanner. This
  356.   method may block while waiting for input. The scanner does not advance past
  357.   any input.
  358.  
  359.   @return true if and only if this scanner has another line of input
  360.   @throws IllegalStateException if this scanner is closed
  361.   */
  362.   public boolean hasNextLine() {
  363.     return _hasNextChar();
  364.   }
  365.  
  366.   /**
  367.   Returns true if the next token in this scanner's input can be interpreted as
  368.   a long value in the default radix using the nextLong() method. The scanner
  369.   does not advance past any input.
  370.  
  371.   @return true if and only if this scanner's next token is a valid long value
  372.   @throws IllegalStateException if this scanner is closed
  373.   */
  374.   public boolean hasNextLong() {
  375.     return hasNextLong(m_radix);
  376.   }
  377.  
  378.   /**
  379.   Returns true if the next token in this scanner's input can be interpreted as
  380.   a long value in the specified radix using the nextLong() method. The scanner
  381.   does not advance past any input.
  382.  
  383.   @return true if and only if this scanner's next token is a valid long value
  384.   @throws IllegalStateException if this scanner is closed
  385.   */
  386.   public boolean hasNextLong(int radix) {
  387.     try {
  388.       nextLong(radix);
  389.       return true;
  390.     } catch (NoSuchElementException nsee) {
  391.       return false;
  392.     } finally {
  393.       _undoNext();
  394.     }
  395.   }
  396.  
  397.   /**
  398.   Returns true if the next token in this scanner's input can be interpreted as
  399.   a short value in the default radix using the nextShort() method. The scanner
  400.   does not advance past any input.
  401.  
  402.   @return true if and only if this scanner's next token is a valid short value
  403.   in the default radix
  404.   @throws IllegalStateException if this scanner is closed
  405.   */
  406.   public boolean hasNextShort() {
  407.     return hasNextShort(m_radix);
  408.   }
  409.  
  410.   /**
  411.   Returns true if the next token in this scanner's input can be interpreted as
  412.   a short value in the specified radix using the nextShort() method. The scanner
  413.   does not advance past any input.
  414.  
  415.   @param radix the radix used to interpret the token as a short value
  416.   @return true if and only if this scanner's next token is a valid short value
  417.   in the specified radix
  418.   @throws IllegalStateException if this scanner is closed
  419.   */
  420.   public boolean hasNextShort(int radix) {
  421.     try {
  422.       nextShort(radix);
  423.       return true;
  424.     } catch (NoSuchElementException nsee) {
  425.       return false;
  426.     } finally {
  427.       _undoNext();
  428.     }
  429.   }
  430.  
  431.   /**
  432.   Returns the IOException last thrown by this Scanner. This method returns
  433.   null if no such exception exists.
  434.  
  435.   @return the last exception thrown by this scanner's readable
  436.   */
  437.   public IOException ioException() {
  438.     return m_ioException;
  439.   }
  440.  
  441.   /**
  442.   Finds and returns the next complete token from this scanner. A complete
  443.   token is preceded and followed by input that matches the delimiter pattern.
  444.   This method may block while waiting for input to scan, even if a previous
  445.   invocation of hasNext() returned true.
  446.  
  447.   @return the next token
  448.   @throws NoSuchElementException if the input is exhausted
  449.   @throws IllegalStateException if this scanner is closed
  450.   */
  451.   public String next() {
  452.     // wipe buffer of characters read by previous call to next()
  453.     m_previousNextBuffer.setLength(0);
  454.    
  455.     try {
  456.       // skip whitespace
  457.       while (_hasNextChar() && _isWhitespace(_peek())) {
  458.         m_previousNextBuffer.append((char)_nextChar());
  459.       }
  460.  
  461.       // build the token
  462.       StringBuffer result = new StringBuffer();
  463.       while (_hasNextChar() && !_isWhitespace(_peek())) {
  464.         char chr = (char)_nextChar();
  465.         result.append(chr);
  466.         m_previousNextBuffer.append(chr);
  467.       }
  468.  
  469.       // make sure token is nonempty      
  470.       if (result.length() == 0)
  471.         throw _getNoSuchElementException();
  472.  
  473.       return result.toString();
  474.     } catch (IOException ioe) {
  475.       _setIoException(ioe);
  476.       return null;
  477.     }
  478.   }
  479.  
  480.   /**
  481.   Scans the next token of the input as a BigDecimal.
  482.  
  483.   @return the BigDecimal scanned from the input
  484.   @throws NoSuchElementException if the input is exhausted
  485.   @throws IllegalStateException if this scanner is closed
  486.   */
  487.   public BigDecimal nextBigDecimal() {
  488.     try {
  489.       return new BigDecimal(_nextToken());
  490.     } catch (NumberFormatException nfe) {
  491.       throw _getNoSuchElementException();
  492.     }
  493.   }
  494.  
  495.   /**
  496.   Scans the next token of the input as a BigInteger.
  497.  
  498.   @return the BigInteger scanned from the input
  499.   @throws NoSuchElementException if the input is exhausted
  500.   @throws IllegalStateException if this scanner is closed
  501.   */
  502.   public BigInteger nextBigInteger() {
  503.     return nextBigInteger(m_radix);
  504.   }
  505.  
  506.   /**
  507.   Scans the next token of the input as a BigInteger.
  508.  
  509.   @param radix the radix used to interpret the token
  510.   @return the BigInteger scanned from the input
  511.   @throws NoSuchElementException if the input is exhausted
  512.   @throws IllegalStateException if this scanner is closed
  513.   */
  514.   public BigInteger nextBigInteger(int radix) {
  515.     try {
  516.       return new BigInteger(_nextToken(), radix);
  517.     } catch (NumberFormatException nfe) {
  518.       throw _getNoSuchElementException();
  519.     }
  520.   }
  521.  
  522.   /**
  523.   Scans the next token of the input into a boolean value and returns that
  524.   value. This method will throw FormatException if the next token cannot
  525.   be translated into a valid boolean value. If the match is successful,
  526.   the scanner advances past the input that matched.
  527.  
  528.   @return the boolean scanned from the input
  529.   @throws NoSuchElementException if the input is exhausted
  530.   @throws IllegalStateException if this scanner is closed
  531.   */
  532.   public boolean nextBoolean() {
  533.     // Boolean.parseBoolean doesn't do what we want here; it assumes all
  534.     // strings other than "true" are false rather than invalid
  535.     String token = _nextToken();
  536.     if (token.equalsIgnoreCase(TRUE))
  537.       return true;
  538.     else if (token.equalsIgnoreCase(FALSE))
  539.       return false;
  540.     else
  541.       throw _getNoSuchElementException();
  542.   }
  543.  
  544.   /**
  545.   Scans the next token of the input as a byte.
  546.  
  547.   <p>
  548.   An invocation of this method of the form nextByte() behaves in exactly the
  549.   same way as the invocation nextByte(radix), where radix is the default radix
  550.   of this scanner.
  551.  
  552.   @return the byte scanned from the input
  553.   @throws NoSuchElementException if input is exhausted
  554.   @throws IllegalStateException if this scanner is closed
  555.   */
  556.   public byte nextByte() {
  557.     return nextByte(m_radix);
  558.   }
  559.  
  560.   /**
  561.   Scans the next token of the input as a byte.
  562.  
  563.   @param radix the radix used to interpret the token as a byte value
  564.   @return the byte scanned from the input
  565.   @throws InputMismatchException if the next token does not match the
  566.   Integer regular expression, or is out of range
  567.   @throws NoSuchElementException if input is exhausted
  568.   @throws IllegalStateException if this scanner is closed
  569.   */
  570.   public byte nextByte(int radix) {
  571.     try {
  572.       return Byte.parseByte(_nextToken());
  573.     } catch (NumberFormatException nfe) {
  574.       throw _getNoSuchElementException();
  575.     }
  576.   }
  577.  
  578.   /**
  579.   Scans the next token of the input as a double. This method will throw
  580.   NumberFormatException if the next token cannot be translated into a valid
  581.   double value. If the translation is successful, the scanner advances past
  582.   the input that matched.
  583.  
  584.   @return the double scanned from the input
  585.   @throws NoSuchElementException if the input is exhausted
  586.   @throws IllegalStateException if this scanner is closed
  587.   */
  588.   public double nextDouble() {
  589.     try {
  590.       return Double.parseDouble(_nextToken());
  591.     } catch (NumberFormatException nfe) {
  592.       throw _getNoSuchElementException();
  593.     }
  594.   }
  595.  
  596.   /**
  597.   Scans the next token of the input as a float. This method will throw
  598.   NumberFormatException if the next token cannot be translated into a valid
  599.   float value. If the translation is successful, the scanner advances past
  600.   the input that matched.
  601.  
  602.   @return the float scanned from the input
  603.   @throws NoSuchElementException if the input is exhausted
  604.   @throws IllegalStateException if this scanner is closed
  605.   */
  606.   public float nextFloat() {
  607.     try {
  608.       return Float.parseFloat(_nextToken());
  609.     } catch (NumberFormatException nfe) {
  610.       throw _getNoSuchElementException();
  611.     }
  612.   }
  613.  
  614.   /**
  615.   Scans the next token of the input as an int. This method will throw
  616.   NumberFormatException if the next token cannot be translated into a valid
  617.   int value. If the translation is successful, the scanner advances past the
  618.   input that matched.
  619.  
  620.   @return the int scanned from the input
  621.   @throws NoSuchElementException if the input is exhausted
  622.   @throws IllegalStateException if this scanner is closed
  623.   */
  624.   public int nextInt() {
  625.     return nextInt(m_radix);
  626.   }
  627.  
  628.   /**
  629.   Scans the next token of the input as an int. This method will throw
  630.   FormatException if the next token cannot be translated into a valid
  631.   int value. If the translation is successful, the scanner advances past the
  632.   input that matched.
  633.  
  634.   @param radix the radix used to interpret the token as an int value
  635.   @return the int scanned from the input
  636.   @throws NoSuchElementException if the input is exhausted
  637.   @throws IllegalStateException if this scanner is closed
  638.   */
  639.   public int nextInt(int radix) {
  640.     try {
  641.       return Integer.parseInt(_nextToken(), radix);
  642.     } catch (NumberFormatException nfe) {
  643.       throw _getNoSuchElementException();
  644.     }
  645.   }
  646.  
  647.   /**
  648.   Advances this scanner past the current line and returns the input that was
  649.   skipped. This method returns the rest of the current line, excluding any
  650.   line separator at the end. The position is set to the beginning of the
  651.   next line.
  652.  
  653.   Since this method continues to search through the input looking for a line
  654.   separator, it may buffer all of the input searching for the line to skip
  655.   if no line separators are present.
  656.  
  657.   @return the line that was skipped
  658.   @throws NoSuchElementException if the input is exhausted
  659.   @throws IllegalStateException if this scanner is closed
  660.   */
  661.   public String nextLine() {
  662.     if (!hasNextLine())
  663.       throw _getNoSuchElementException();
  664.    
  665.     StringBuffer result = new StringBuffer();
  666.     while (_hasNextChar()) {
  667.       char next = (char)_nextChar();
  668.      
  669.       // don't put the newline separator into the result
  670.       if (next == '\n')
  671.         break;
  672.       else if (next == '\r')
  673.         continue;
  674.      
  675.       result.append(next);
  676.     }
  677.  
  678.     return result.toString();
  679.   }
  680.  
  681.   /**
  682.   Scans the next token of the input as a long. This method will throw
  683.   NumberFormatException if the next token cannot be translated into a valid
  684.   long value. If the translation is successful, the scanner advances past the
  685.   input that matched.
  686.  
  687.   @return the long scanned from the input
  688.   @throws NoSuchElementException if the input is exhausted
  689.   @throws IllegalStateException if this scanner is closed
  690.   */
  691.   public long nextLong() {
  692.     return nextLong(m_radix);
  693.   }
  694.  
  695.   /**
  696.   Scans the next token of the input as a long. This method will throw
  697.   FormatException if the next token cannot be translated into a valid
  698.   long value. If the translation is successful, the scanner advances past the
  699.   input that matched.
  700.  
  701.   @param radix the radix used to interpret the token as a long value
  702.   @return the long scanned from the input
  703.   @throws NoSuchElementException if the input is exhausted
  704.   @throws IllegalStateException if this scanner is closed
  705.   */
  706.   public long nextLong(int radix) {
  707.     try {
  708.       return Long.parseLong(_nextToken(), radix);
  709.     } catch (NumberFormatException nfe) {
  710.       throw _getNoSuchElementException();
  711.     }
  712.   }
  713.  
  714.   /**
  715.   Scans the next token of the input as a short. This method will throw
  716.   NumberFormatException if the next token cannot be translated into a valid
  717.   short value. If the translation is successful, the scanner advances past the
  718.   input that matched.
  719.  
  720.   @return the short scanned from the input
  721.   @throws NoSuchElementException if the input is exhausted
  722.   @throws IllegalStateException if this scanner is closed
  723.   */
  724.   public short nextShort() {
  725.     return nextShort(m_radix);
  726.   }
  727.  
  728.   /**
  729.   Scans the next token of the input as a short. This method will throw
  730.   FormatException if the next token cannot be translated into a valid
  731.   short value. If the translation is successful, the scanner advances past the
  732.   input that matched.
  733.  
  734.   @param radix the radix used to interpret the token as a short value
  735.   @return the long scanned from the input
  736.   @throws NoSuchElementException if the input is exhausted
  737.   @throws IllegalStateException if this scanner is closed
  738.   */
  739.   public short nextShort(int radix) {
  740.     try {
  741.       return Short.parseShort(_nextToken(), radix);
  742.     } catch (NumberFormatException nfe) {
  743.       throw _getNoSuchElementException();
  744.     }
  745.   }
  746.  
  747.   /**
  748.   Returns this scanner's default radix.
  749.  
  750.   <p>
  751.   A scanner's radix affects elements of its default number matching
  752.   regular expressions.
  753.  
  754.   @return the default radix of this scanner
  755.   @throws NoSuchElementException if the input is exhausted
  756.   @throws IllegalStateException if this scanner is closed
  757.   */
  758.   public int radix() {
  759.     return m_radix;
  760.   }
  761.  
  762.   /**
  763.   The remove operation is not supported by this implementation of Iterator.
  764.  
  765.   @throws UnsupportedOperationException if this method is invoked.
  766.   */
  767.   public void remove() {
  768.     throw new UnsupportedOperationException(REMOVE_EXCEPTION_MESSAGE);
  769.   }
  770.  
  771.   /**
  772.   Returns the string representation of this Scanner. The string
  773.   representation of a Scanner contains information that may be useful
  774.   for debugging. The exact format is unspecified.
  775.  
  776.   @return The string representation of this scanner
  777.   */
  778.   public String toString() {
  779.     return getClass().getName();
  780.   }
  781.  
  782.   /**
  783.   Sets this scanner's default radix to the specified radix.
  784.  
  785.   <p>
  786.   A scanner's radix affects elements of its default number matching
  787.   regular expressions.
  788.  
  789.   <p>
  790.   If the radix is less than Character.MIN_RADIX or greater than
  791.   Character.MAX_RADIX, then an IllegalArgumentException is thrown.
  792.  
  793.   @throws IllegalArgumentException if radix is out of range
  794.   */
  795.   public Scanner useRadix(int radix) {
  796.     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
  797.       throw new IllegalArgumentException();
  798.    
  799.     m_radix = radix;
  800.     return this;
  801.   }
  802.  
  803.   // common function to make sure input has not been exhausted
  804.   private boolean _hasNextChar() {
  805.     try {
  806.       int chr = _nextChar();
  807.       if (chr == EOF)
  808.         return false;
  809.      
  810.       _unread(chr);
  811.       return true;
  812.     } catch (IOException ioe) {
  813.       _setIoException(ioe);
  814.       return false;
  815.     } catch (NoSuchElementException nsee) {
  816.       return false;
  817.     }
  818.   }
  819.  
  820.   // returns whether the given character is a whitespace character
  821.   private boolean _isWhitespace(int chr) {
  822.     return DELIMITER.indexOf((char)chr) >= 0;
  823.   }
  824.  
  825.   // advances one character in the input
  826.   private int _nextChar() {
  827.     if (m_closed)
  828.       throw new IllegalStateException();
  829.  
  830.     try {
  831.       return m_reader.read();    
  832.     } catch (IOException ioe) {
  833.       _setIoException(ioe);
  834.       return EOF;
  835.     }
  836.   }
  837.  
  838.   // advances one token in the input
  839.   private String _nextToken() {
  840.     return (String)next();
  841.   }
  842.  
  843.   // returns next character in the input without advancing the reader
  844.   private int _peek() throws IOException {
  845.     int peekChar = _nextChar();
  846.     _unread(peekChar);
  847.     return peekChar;
  848.   }
  849.  
  850.   private NoSuchElementException _getNoSuchElementException() {
  851.     int lineNum = m_lnReader.getLineNumber();
  852.     return new NoSuchElementException(BAD_INPUT_EXCEPTION_MESSAGE + lineNum);
  853.   }
  854.  
  855.   // sets internal io exception
  856.   private void _setIoException(IOException ioe) {
  857.     m_ioException = ioe;
  858.     ioe.printStackTrace();
  859.   }
  860.  
  861.   // unreads buffer of characters that were consumed by
  862.   // the last call to next()
  863.   private void _undoNext() {
  864.     if (m_previousNextBuffer.length() > 0) {
  865.       try {
  866.         m_reader.unread(m_previousNextBuffer.toString().toCharArray());
  867.       } catch (IOException ioe) {
  868.         _setIoException(ioe);
  869.       }
  870.     }
  871.   }
  872.  
  873.   // put given value back into the input stream
  874.   private void _unread(int chr) throws IOException {
  875.     m_reader.unread(chr);
  876.   }
  877. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement