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