KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > LineNumberInputStream


1 /*
2  * @(#)LineNumberInputStream.java 1.27 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10 /**
11  * This class is an input stream filter that provides the added
12  * functionality of keeping track of the current line number.
13  * <p>
14  * A line is a sequence of bytes ending with a carriage return
15  * character (<code>'&#92;r'</code>), a newline character
16  * (<code>'&#92;n'</code>), or a carriage return character followed
17  * immediately by a linefeed character. In all three cases, the line
18  * terminating character(s) are returned as a single newline character.
19  * <p>
20  * The line number begins at <code>0</code>, and is incremented by
21  * <code>1</code> when a <code>read</code> returns a newline character.
22  *
23  * @author Arthur van Hoff
24  * @version 1.27, 05/18/04
25  * @see java.io.LineNumberReader
26  * @since JDK1.0
27  * @deprecated This class incorrectly assumes that bytes adequately represent
28  * characters. As of JDK&nbsp;1.1, the preferred way to operate on
29  * character streams is via the new character-stream classes, which
30  * include a class for counting line numbers.
31  */

32 @Deprecated JavaDoc
33 public
34 class LineNumberInputStream extends FilterInputStream JavaDoc {
35     int pushBack = -1;
36     int lineNumber;
37     int markLineNumber;
38     int markPushBack = -1;
39     
40     /**
41      * Constructs a newline number input stream that reads its input
42      * from the specified input stream.
43      *
44      * @param in the underlying input stream.
45      */

46     public LineNumberInputStream(InputStream JavaDoc in) {
47     super(in);
48     }
49
50     /**
51      * Reads the next byte of data from this input stream. The value
52      * byte is returned as an <code>int</code> in the range
53      * <code>0</code> to <code>255</code>. If no byte is available
54      * because the end of the stream has been reached, the value
55      * <code>-1</code> is returned. This method blocks until input data
56      * is available, the end of the stream is detected, or an exception
57      * is thrown.
58      * <p>
59      * The <code>read</code> method of
60      * <code>LineNumberInputStream</code> calls the <code>read</code>
61      * method of the underlying input stream. It checks for carriage
62      * returns and newline characters in the input, and modifies the
63      * current line number as appropriate. A carriage-return character or
64      * a carriage return followed by a newline character are both
65      * converted into a single newline character.
66      *
67      * @return the next byte of data, or <code>-1</code> if the end of this
68      * stream is reached.
69      * @exception IOException if an I/O error occurs.
70      * @see java.io.FilterInputStream#in
71      * @see java.io.LineNumberInputStream#getLineNumber()
72      */

73     public int read() throws IOException JavaDoc {
74     int c = pushBack;
75
76     if (c != -1) {
77         pushBack = -1;
78     } else {
79         c = in.read();
80     }
81
82     switch (c) {
83       case '\r':
84         pushBack = in.read();
85         if (pushBack == '\n') {
86         pushBack = -1;
87         }
88       case '\n':
89         lineNumber++;
90         return '\n';
91     }
92     return c;
93     }
94
95     /**
96      * Reads up to <code>len</code> bytes of data from this input stream
97      * into an array of bytes. This method blocks until some input is available.
98      * <p>
99      * The <code>read</code> method of
100      * <code>LineNumberInputStream</code> repeatedly calls the
101      * <code>read</code> method of zero arguments to fill in the byte array.
102      *
103      * @param b the buffer into which the data is read.
104      * @param off the start offset of the data.
105      * @param len the maximum number of bytes read.
106      * @return the total number of bytes read into the buffer, or
107      * <code>-1</code> if there is no more data because the end of
108      * this stream has been reached.
109      * @exception IOException if an I/O error occurs.
110      * @see java.io.LineNumberInputStream#read()
111      */

112     public int read(byte b[], int off, int len) throws IOException JavaDoc {
113     if (b == null) {
114         throw new NullPointerException JavaDoc();
115     } else if ((off < 0) || (off > b.length) || (len < 0) ||
116            ((off + len) > b.length) || ((off + len) < 0)) {
117         throw new IndexOutOfBoundsException JavaDoc();
118     } else if (len == 0) {
119         return 0;
120     }
121
122     int c = read();
123     if (c == -1) {
124         return -1;
125     }
126     b[off] = (byte)c;
127
128     int i = 1;
129     try {
130         for (; i < len ; i++) {
131         c = read();
132         if (c == -1) {
133             break;
134         }
135         if (b != null) {
136             b[off + i] = (byte)c;
137         }
138         }
139     } catch (IOException JavaDoc ee) {
140     }
141     return i;
142     }
143
144     /**
145      * Skips over and discards <code>n</code> bytes of data from this
146      * input stream. The <code>skip</code> method may, for a variety of
147      * reasons, end up skipping over some smaller number of bytes,
148      * possibly <code>0</code>. The actual number of bytes skipped is
149      * returned. If <code>n</code> is negative, no bytes are skipped.
150      * <p>
151      * The <code>skip</code> method of <code>LineNumberInputStream</code> creates
152      * a byte array and then repeatedly reads into it until
153      * <code>n</code> bytes have been read or the end of the stream has
154      * been reached.
155      *
156      * @param n the number of bytes to be skipped.
157      * @return the actual number of bytes skipped.
158      * @exception IOException if an I/O error occurs.
159      * @see java.io.FilterInputStream#in
160      */

161     public long skip(long n) throws IOException JavaDoc {
162     int chunk = 2048;
163     long remaining = n;
164     byte data[];
165     int nr;
166
167     if (n <= 0) {
168         return 0;
169     }
170     
171     data = new byte[chunk];
172     while (remaining > 0) {
173         nr = read(data, 0, (int) Math.min(chunk, remaining));
174         if (nr < 0) {
175         break;
176         }
177         remaining -= nr;
178     }
179     
180     return n - remaining;
181     }
182
183     /**
184      * Sets the line number to the specified argument.
185      *
186      * @param lineNumber the new line number.
187      * @see #getLineNumber
188      */

189     public void setLineNumber(int lineNumber) {
190     this.lineNumber = lineNumber;
191     }
192
193     /**
194      * Returns the current line number.
195      *
196      * @return the current line number.
197      * @see #setLineNumber
198      */

199     public int getLineNumber() {
200     return lineNumber;
201     }
202
203    
204     /**
205      * Returns the number of bytes that can be read from this input
206      * stream without blocking.
207      * <p>
208      * Note that if the underlying input stream is able to supply
209      * <i>k</i> input characters without blocking, the
210      * <code>LineNumberInputStream</code> can guarantee only to provide
211      * <i>k</i>/2 characters without blocking, because the
212      * <i>k</i> characters from the underlying input stream might
213      * consist of <i>k</i>/2 pairs of <code>'&#92;r'</code> and
214      * <code>'&#92;n'</code>, which are converted to just
215      * <i>k</i>/2 <code>'&#92;n'</code> characters.
216      *
217      * @return the number of bytes that can be read from this input stream
218      * without blocking.
219      * @exception IOException if an I/O error occurs.
220      * @see java.io.FilterInputStream#in
221      */

222     public int available() throws IOException JavaDoc {
223     return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
224     }
225
226     /**
227      * Marks the current position in this input stream. A subsequent
228      * call to the <code>reset</code> method repositions this stream at
229      * the last marked position so that subsequent reads re-read the same bytes.
230      * <p>
231      * The <code>mark</code> method of
232      * <code>LineNumberInputStream</code> remembers the current line
233      * number in a private variable, and then calls the <code>mark</code>
234      * method of the underlying input stream.
235      *
236      * @param readlimit the maximum limit of bytes that can be read before
237      * the mark position becomes invalid.
238      * @see java.io.FilterInputStream#in
239      * @see java.io.LineNumberInputStream#reset()
240      */

241     public void mark(int readlimit) {
242     markLineNumber = lineNumber;
243         markPushBack = pushBack;
244     in.mark(readlimit);
245     }
246
247     /**
248      * Repositions this stream to the position at the time the
249      * <code>mark</code> method was last called on this input stream.
250      * <p>
251      * The <code>reset</code> method of
252      * <code>LineNumberInputStream</code> resets the line number to be
253      * the line number at the time the <code>mark</code> method was
254      * called, and then calls the <code>reset</code> method of the
255      * underlying input stream.
256      * <p>
257      * Stream marks are intended to be used in
258      * situations where you need to read ahead a little to see what's in
259      * the stream. Often this is most easily done by invoking some
260      * general parser. If the stream is of the type handled by the
261      * parser, it just chugs along happily. If the stream is not of
262      * that type, the parser should toss an exception when it fails,
263      * which, if it happens within readlimit bytes, allows the outer
264      * code to reset the stream and try another parser.
265      *
266      * @exception IOException if an I/O error occurs.
267      * @see java.io.FilterInputStream#in
268      * @see java.io.LineNumberInputStream#mark(int)
269      */

270     public void reset() throws IOException JavaDoc {
271     lineNumber = markLineNumber;
272         pushBack = markPushBack;
273     in.reset();
274     }
275 }
276
Popular Tags