Mercurial Hosting > luan
annotate src/goodjava/io/BufferedInputStream.java @ 1586:fcca0ddf5a4d
luan uses goodjava.mail
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 12 Mar 2021 20:12:43 -0700 |
parents | 91c167099462 |
children |
rev | line source |
---|---|
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1 /* |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
4 */ |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
5 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
6 package goodjava.io; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
7 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
8 import java.io.InputStream; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
9 import java.io.IOException; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
10 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
11 /** |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
12 * A <code>BufferedInputStream</code> adds |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
13 * functionality to another input stream-namely, |
1480 | 14 * the ability to buffer the input. When the <code>BufferedInputStream</code> |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
15 * is created, an internal buffer array is |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
16 * created. As bytes from the stream are read |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
17 * or skipped, the internal buffer is refilled |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
18 * as necessary from the contained input stream, |
1480 | 19 * many bytes at a time. |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
20 * |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
21 * @author Arthur van Hoff |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
22 * @since JDK1.0 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
23 */ |
1494 | 24 public final class BufferedInputStream extends NoMarkInputStream { |
1480 | 25 private final byte buf[]; |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
26 |
1479 | 27 /** |
28 * The index one greater than the index of the last valid byte in | |
29 * the buffer. | |
30 * This value is always | |
31 * in the range <code>0</code> through <code>buf.length</code>; | |
32 * elements <code>buf[0]</code> through <code>buf[count-1] | |
33 * </code>contain buffered input data obtained | |
1480 | 34 * from the underlying input stream. |
1479 | 35 */ |
1480 | 36 private int count; |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
37 |
1479 | 38 /** |
39 * The current position in the buffer. This is the index of the next | |
40 * character to be read from the <code>buf</code> array. | |
41 * <p> | |
42 * This value is always in the range <code>0</code> | |
43 * through <code>count</code>. If it is less | |
44 * than <code>count</code>, then <code>buf[pos]</code> | |
45 * is the next byte to be supplied as input; | |
46 * if it is equal to <code>count</code>, then | |
47 * the next <code>read</code> or <code>skip</code> | |
48 * operation will require more bytes to be | |
49 * read from the contained input stream. | |
50 * | |
51 * @see java.io.BufferedInputStream#buf | |
52 */ | |
1480 | 53 private int pos; |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
54 |
1479 | 55 /** |
56 * Creates a <code>BufferedInputStream</code> | |
57 * and saves its argument, the input stream | |
58 * <code>in</code>, for later use. An internal | |
59 * buffer array is created and stored in <code>buf</code>. | |
60 * | |
61 * @param in the underlying input stream. | |
62 */ | |
63 public BufferedInputStream(InputStream in) { | |
1483 | 64 this(in, 8192); |
1479 | 65 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
66 |
1479 | 67 /** |
68 * Creates a <code>BufferedInputStream</code> | |
69 * with the specified buffer size, | |
70 * and saves its argument, the input stream | |
71 * <code>in</code>, for later use. An internal | |
72 * buffer array of length <code>size</code> | |
73 * is created and stored in <code>buf</code>. | |
74 * | |
75 * @param in the underlying input stream. | |
76 * @param size the buffer size. | |
77 */ | |
78 public BufferedInputStream(InputStream in, int size) { | |
79 super(in); | |
80 buf = new byte[size]; | |
81 } | |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
82 |
1479 | 83 /** |
1480 | 84 * Fills the buffer with more data. |
1479 | 85 * This method also assumes that all data has already been read in, |
86 * hence pos > count. | |
87 */ | |
88 private void fill() throws IOException { | |
1480 | 89 pos = 0; |
90 count = 0; | |
1494 | 91 int n = in.read(buf, 0, buf.length); |
1479 | 92 if (n > 0) |
1480 | 93 count = n; |
1479 | 94 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
95 |
1479 | 96 /** |
97 * See | |
98 * the general contract of the <code>read</code> | |
99 * method of <code>InputStream</code>. | |
100 * | |
101 * @return the next byte of data, or <code>-1</code> if the end of the | |
102 * stream is reached. | |
103 * @exception IOException if this input stream has been closed by | |
104 * invoking its {@link #close()} method, | |
105 * or an I/O error occurs. | |
106 * @see java.io.FilterInputStream#in | |
107 */ | |
1494 | 108 public int read() throws IOException { |
1479 | 109 if (pos >= count) { |
110 fill(); | |
111 if (pos >= count) | |
112 return -1; | |
113 } | |
1480 | 114 return buf[pos++] & 0xff; |
1479 | 115 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
116 |
1479 | 117 /** |
118 * Read characters into a portion of an array, reading from the underlying | |
119 * stream at most once if necessary. | |
120 */ | |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
121 private int read1(byte[] b, int off, int len) throws IOException { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
122 int cnt = 0; |
1479 | 123 int avail = count - pos; |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
124 if( avail > 0 ) { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
125 cnt = (avail < len) ? avail : len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
126 System.arraycopy(buf, pos, b, off, cnt); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
127 pos += cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
128 len -= cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
129 if( len == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
130 return cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
131 off += cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
132 } |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
133 if (len >= buf.length) { |
1494 | 134 return cnt + Math.max( 0, in.read(b, off, len) ); |
1479 | 135 } |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
136 fill(); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
137 if (count <= 0) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
138 return cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
139 System.arraycopy(buf, 0, b, off, len); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
140 pos += len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
141 return cnt + len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
142 } |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
143 |
1494 | 144 public int read(byte[] b, int off, int len) throws IOException { |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
145 if( len == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
146 return 0; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
147 int n = read1(b,off,len); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
148 return n==0 ? -1 : n; |
1479 | 149 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
150 |
1479 | 151 /** |
152 * See the general contract of the <code>skip</code> | |
153 * method of <code>InputStream</code>. | |
154 * | |
155 * @exception IOException if the stream does not support seek, | |
156 * or if this input stream has been closed by | |
157 * invoking its {@link #close()} method, or an | |
158 * I/O error occurs. | |
159 */ | |
1494 | 160 public long skip(long n) throws IOException { |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
161 if( n <= 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
162 return 0; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
163 long skipped = 0; |
1479 | 164 long avail = count - pos; |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
165 if( avail > 0 ) { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
166 skipped = (avail < n) ? avail : n; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
167 pos += skipped; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
168 n -= skipped; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
169 if( n == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
170 return skipped; |
1479 | 171 } |
1494 | 172 return skipped + in.skip(n); |
1479 | 173 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
174 |
1479 | 175 /** |
176 * Returns an estimate of the number of bytes that can be read (or | |
177 * skipped over) from this input stream without blocking by the next | |
178 * invocation of a method for this input stream. The next invocation might be | |
179 * the same thread or another thread. A single read or skip of this | |
180 * many bytes will not block, but may read or skip fewer bytes. | |
181 * <p> | |
182 * This method returns the sum of the number of bytes remaining to be read in | |
183 * the buffer (<code>count - pos</code>) and the result of calling the | |
184 * {@link java.io.FilterInputStream#in in}.available(). | |
185 * | |
186 * @return an estimate of the number of bytes that can be read (or skipped | |
187 * over) from this input stream without blocking. | |
188 * @exception IOException if this input stream has been closed by | |
189 * invoking its {@link #close()} method, | |
190 * or an I/O error occurs. | |
191 */ | |
1494 | 192 public int available() throws IOException { |
1479 | 193 int n = count - pos; |
1494 | 194 int avail = in.available(); |
1479 | 195 return n > (Integer.MAX_VALUE - avail) |
196 ? Integer.MAX_VALUE | |
197 : n + avail; | |
198 } | |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
199 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
200 } |