rt/emul/compact/src/main/java/java/io/LineNumberInputStream.java
author Jaroslav Tulach <jtulach@netbeans.org>
Thu, 03 Oct 2013 15:40:35 +0200
branchjdk7-b147
changeset 1334 588d5bf7a560
permissions -rw-r--r--
Set of JDK classes needed to run javac
     1 /*
     2  * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.io;
    27 
    28 /**
    29  * This class is an input stream filter that provides the added
    30  * functionality of keeping track of the current line number.
    31  * <p>
    32  * A line is a sequence of bytes ending with a carriage return
    33  * character (<code>'&#92;r'</code>), a newline character
    34  * (<code>'&#92;n'</code>), or a carriage return character followed
    35  * immediately by a linefeed character. In all three cases, the line
    36  * terminating character(s) are returned as a single newline character.
    37  * <p>
    38  * The line number begins at <code>0</code>, and is incremented by
    39  * <code>1</code> when a <code>read</code> returns a newline character.
    40  *
    41  * @author     Arthur van Hoff
    42  * @see        java.io.LineNumberReader
    43  * @since      JDK1.0
    44  * @deprecated This class incorrectly assumes that bytes adequately represent
    45  *             characters.  As of JDK&nbsp;1.1, the preferred way to operate on
    46  *             character streams is via the new character-stream classes, which
    47  *             include a class for counting line numbers.
    48  */
    49 @Deprecated
    50 public
    51 class LineNumberInputStream extends FilterInputStream {
    52     int pushBack = -1;
    53     int lineNumber;
    54     int markLineNumber;
    55     int markPushBack = -1;
    56 
    57     /**
    58      * Constructs a newline number input stream that reads its input
    59      * from the specified input stream.
    60      *
    61      * @param      in   the underlying input stream.
    62      */
    63     public LineNumberInputStream(InputStream in) {
    64         super(in);
    65     }
    66 
    67     /**
    68      * Reads the next byte of data from this input stream. The value
    69      * byte is returned as an <code>int</code> in the range
    70      * <code>0</code> to <code>255</code>. If no byte is available
    71      * because the end of the stream has been reached, the value
    72      * <code>-1</code> is returned. This method blocks until input data
    73      * is available, the end of the stream is detected, or an exception
    74      * is thrown.
    75      * <p>
    76      * The <code>read</code> method of
    77      * <code>LineNumberInputStream</code> calls the <code>read</code>
    78      * method of the underlying input stream. It checks for carriage
    79      * returns and newline characters in the input, and modifies the
    80      * current line number as appropriate. A carriage-return character or
    81      * a carriage return followed by a newline character are both
    82      * converted into a single newline character.
    83      *
    84      * @return     the next byte of data, or <code>-1</code> if the end of this
    85      *             stream is reached.
    86      * @exception  IOException  if an I/O error occurs.
    87      * @see        java.io.FilterInputStream#in
    88      * @see        java.io.LineNumberInputStream#getLineNumber()
    89      */
    90     public int read() throws IOException {
    91         int c = pushBack;
    92 
    93         if (c != -1) {
    94             pushBack = -1;
    95         } else {
    96             c = in.read();
    97         }
    98 
    99         switch (c) {
   100           case '\r':
   101             pushBack = in.read();
   102             if (pushBack == '\n') {
   103                 pushBack = -1;
   104             }
   105           case '\n':
   106             lineNumber++;
   107             return '\n';
   108         }
   109         return c;
   110     }
   111 
   112     /**
   113      * Reads up to <code>len</code> bytes of data from this input stream
   114      * into an array of bytes. This method blocks until some input is available.
   115      * <p>
   116      * The <code>read</code> method of
   117      * <code>LineNumberInputStream</code> repeatedly calls the
   118      * <code>read</code> method of zero arguments to fill in the byte array.
   119      *
   120      * @param      b     the buffer into which the data is read.
   121      * @param      off   the start offset of the data.
   122      * @param      len   the maximum number of bytes read.
   123      * @return     the total number of bytes read into the buffer, or
   124      *             <code>-1</code> if there is no more data because the end of
   125      *             this stream has been reached.
   126      * @exception  IOException  if an I/O error occurs.
   127      * @see        java.io.LineNumberInputStream#read()
   128      */
   129     public int read(byte b[], int off, int len) throws IOException {
   130         if (b == null) {
   131             throw new NullPointerException();
   132         } else if ((off < 0) || (off > b.length) || (len < 0) ||
   133                    ((off + len) > b.length) || ((off + len) < 0)) {
   134             throw new IndexOutOfBoundsException();
   135         } else if (len == 0) {
   136             return 0;
   137         }
   138 
   139         int c = read();
   140         if (c == -1) {
   141             return -1;
   142         }
   143         b[off] = (byte)c;
   144 
   145         int i = 1;
   146         try {
   147             for (; i < len ; i++) {
   148                 c = read();
   149                 if (c == -1) {
   150                     break;
   151                 }
   152                 if (b != null) {
   153                     b[off + i] = (byte)c;
   154                 }
   155             }
   156         } catch (IOException ee) {
   157         }
   158         return i;
   159     }
   160 
   161     /**
   162      * Skips over and discards <code>n</code> bytes of data from this
   163      * input stream. The <code>skip</code> method may, for a variety of
   164      * reasons, end up skipping over some smaller number of bytes,
   165      * possibly <code>0</code>. The actual number of bytes skipped is
   166      * returned.  If <code>n</code> is negative, no bytes are skipped.
   167      * <p>
   168      * The <code>skip</code> method of <code>LineNumberInputStream</code> creates
   169      * a byte array and then repeatedly reads into it until
   170      * <code>n</code> bytes have been read or the end of the stream has
   171      * been reached.
   172      *
   173      * @param      n   the number of bytes to be skipped.
   174      * @return     the actual number of bytes skipped.
   175      * @exception  IOException  if an I/O error occurs.
   176      * @see        java.io.FilterInputStream#in
   177      */
   178     public long skip(long n) throws IOException {
   179         int chunk = 2048;
   180         long remaining = n;
   181         byte data[];
   182         int nr;
   183 
   184         if (n <= 0) {
   185             return 0;
   186         }
   187 
   188         data = new byte[chunk];
   189         while (remaining > 0) {
   190             nr = read(data, 0, (int) Math.min(chunk, remaining));
   191             if (nr < 0) {
   192                 break;
   193             }
   194             remaining -= nr;
   195         }
   196 
   197         return n - remaining;
   198     }
   199 
   200     /**
   201      * Sets the line number to the specified argument.
   202      *
   203      * @param      lineNumber   the new line number.
   204      * @see #getLineNumber
   205      */
   206     public void setLineNumber(int lineNumber) {
   207         this.lineNumber = lineNumber;
   208     }
   209 
   210     /**
   211      * Returns the current line number.
   212      *
   213      * @return     the current line number.
   214      * @see #setLineNumber
   215      */
   216     public int getLineNumber() {
   217         return lineNumber;
   218     }
   219 
   220 
   221     /**
   222      * Returns the number of bytes that can be read from this input
   223      * stream without blocking.
   224      * <p>
   225      * Note that if the underlying input stream is able to supply
   226      * <i>k</i> input characters without blocking, the
   227      * <code>LineNumberInputStream</code> can guarantee only to provide
   228      * <i>k</i>/2 characters without blocking, because the
   229      * <i>k</i> characters from the underlying input stream might
   230      * consist of <i>k</i>/2 pairs of <code>'&#92;r'</code> and
   231      * <code>'&#92;n'</code>, which are converted to just
   232      * <i>k</i>/2 <code>'&#92;n'</code> characters.
   233      *
   234      * @return     the number of bytes that can be read from this input stream
   235      *             without blocking.
   236      * @exception  IOException  if an I/O error occurs.
   237      * @see        java.io.FilterInputStream#in
   238      */
   239     public int available() throws IOException {
   240         return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
   241     }
   242 
   243     /**
   244      * Marks the current position in this input stream. A subsequent
   245      * call to the <code>reset</code> method repositions this stream at
   246      * the last marked position so that subsequent reads re-read the same bytes.
   247      * <p>
   248      * The <code>mark</code> method of
   249      * <code>LineNumberInputStream</code> remembers the current line
   250      * number in a private variable, and then calls the <code>mark</code>
   251      * method of the underlying input stream.
   252      *
   253      * @param   readlimit   the maximum limit of bytes that can be read before
   254      *                      the mark position becomes invalid.
   255      * @see     java.io.FilterInputStream#in
   256      * @see     java.io.LineNumberInputStream#reset()
   257      */
   258     public void mark(int readlimit) {
   259         markLineNumber = lineNumber;
   260         markPushBack   = pushBack;
   261         in.mark(readlimit);
   262     }
   263 
   264     /**
   265      * Repositions this stream to the position at the time the
   266      * <code>mark</code> method was last called on this input stream.
   267      * <p>
   268      * The <code>reset</code> method of
   269      * <code>LineNumberInputStream</code> resets the line number to be
   270      * the line number at the time the <code>mark</code> method was
   271      * called, and then calls the <code>reset</code> method of the
   272      * underlying input stream.
   273      * <p>
   274      * Stream marks are intended to be used in
   275      * situations where you need to read ahead a little to see what's in
   276      * the stream. Often this is most easily done by invoking some
   277      * general parser. If the stream is of the type handled by the
   278      * parser, it just chugs along happily. If the stream is not of
   279      * that type, the parser should toss an exception when it fails,
   280      * which, if it happens within readlimit bytes, allows the outer
   281      * code to reset the stream and try another parser.
   282      *
   283      * @exception  IOException  if an I/O error occurs.
   284      * @see        java.io.FilterInputStream#in
   285      * @see        java.io.LineNumberInputStream#mark(int)
   286      */
   287     public void reset() throws IOException {
   288         lineNumber = markLineNumber;
   289         pushBack   = markPushBack;
   290         in.reset();
   291     }
   292 }