Path: blob/master/src/java.base/share/classes/java/io/ByteArrayInputStream.java
67794 views
/*1* Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.io;2627import java.util.Arrays;28import java.util.Objects;2930/**31* A {@code ByteArrayInputStream} contains32* an internal buffer that contains bytes that33* may be read from the stream. An internal34* counter keeps track of the next byte to35* be supplied by the {@code read} method.36* <p>37* Closing a {@code ByteArrayInputStream} has no effect. The methods in38* this class can be called after the stream has been closed without39* generating an {@code IOException}.40*41* @author Arthur van Hoff42* @see java.io.StringBufferInputStream43* @since 1.044*/45public class ByteArrayInputStream extends InputStream {4647/**48* An array of bytes that was provided49* by the creator of the stream. Elements {@code buf[0]}50* through {@code buf[count-1]} are the51* only bytes that can ever be read from the52* stream; element {@code buf[pos]} is53* the next byte to be read.54*/55protected byte buf[];5657/**58* The index of the next character to read from the input stream buffer.59* This value should always be nonnegative60* and not larger than the value of {@code count}.61* The next byte to be read from the input stream buffer62* will be {@code buf[pos]}.63*/64protected int pos;6566/**67* The currently marked position in the stream.68* ByteArrayInputStream objects are marked at position zero by69* default when constructed. They may be marked at another70* position within the buffer by the {@code mark()} method.71* The current buffer position is set to this point by the72* {@code reset()} method.73* <p>74* If no mark has been set, then the value of mark is the offset75* passed to the constructor (or 0 if the offset was not supplied).76*77* @since 1.178*/79protected int mark = 0;8081/**82* The index one greater than the last valid character in the input83* stream buffer.84* This value should always be nonnegative85* and not larger than the length of {@code buf}.86* It is one greater than the position of87* the last byte within {@code buf} that88* can ever be read from the input stream buffer.89*/90protected int count;9192/**93* Creates a {@code ByteArrayInputStream}94* so that it uses {@code buf} as its95* buffer array.96* The buffer array is not copied.97* The initial value of {@code pos}98* is {@code 0} and the initial value99* of {@code count} is the length of100* {@code buf}.101*102* @param buf the input buffer.103*/104public ByteArrayInputStream(byte buf[]) {105this.buf = buf;106this.pos = 0;107this.count = buf.length;108}109110/**111* Creates {@code ByteArrayInputStream}112* that uses {@code buf} as its113* buffer array. The initial value of {@code pos}114* is {@code offset} and the initial value115* of {@code count} is the minimum of {@code offset+length}116* and {@code buf.length}.117* The buffer array is not copied. The buffer's mark is118* set to the specified offset.119*120* @param buf the input buffer.121* @param offset the offset in the buffer of the first byte to read.122* @param length the maximum number of bytes to read from the buffer.123*/124public ByteArrayInputStream(byte buf[], int offset, int length) {125this.buf = buf;126this.pos = offset;127this.count = Math.min(offset + length, buf.length);128this.mark = offset;129}130131/**132* Reads the next byte of data from this input stream. The value133* byte is returned as an {@code int} in the range134* {@code 0} to {@code 255}. If no byte is available135* because the end of the stream has been reached, the value136* {@code -1} is returned.137* <p>138* This {@code read} method139* cannot block.140*141* @return the next byte of data, or {@code -1} if the end of the142* stream has been reached.143*/144public synchronized int read() {145return (pos < count) ? (buf[pos++] & 0xff) : -1;146}147148/**149* Reads up to {@code len} bytes of data into an array of bytes from this150* input stream. If {@code pos} equals {@code count}, then {@code -1} is151* returned to indicate end of file. Otherwise, the number {@code k} of152* bytes read is equal to the smaller of {@code len} and {@code count-pos}.153* If {@code k} is positive, then bytes {@code buf[pos]} through154* {@code buf[pos+k-1]} are copied into {@code b[off]} through155* {@code b[off+k-1]} in the manner performed by {@code System.arraycopy}.156* The value {@code k} is added into {@code pos} and {@code k} is returned.157* <p>158* Unlike the {@link InputStream#read(byte[],int,int) overridden method}159* of {@code InputStream}, this method returns {@code -1} instead of zero160* if the end of the stream has been reached and {@code len == 0}.161* <p>162* This {@code read} method cannot block.163*164* @param b the buffer into which the data is read.165* @param off the start offset in the destination array {@code b}166* @param len the maximum number of bytes read.167* @return the total number of bytes read into the buffer, or168* {@code -1} if there is no more data because the end of169* the stream has been reached.170* @throws NullPointerException If {@code b} is {@code null}.171* @throws IndexOutOfBoundsException If {@code off} is negative,172* {@code len} is negative, or {@code len} is greater than173* {@code b.length - off}174*/175public synchronized int read(byte b[], int off, int len) {176Objects.checkFromIndexSize(off, len, b.length);177178if (pos >= count) {179return -1;180}181182int avail = count - pos;183if (len > avail) {184len = avail;185}186if (len <= 0) {187return 0;188}189System.arraycopy(buf, pos, b, off, len);190pos += len;191return len;192}193194public synchronized byte[] readAllBytes() {195byte[] result = Arrays.copyOfRange(buf, pos, count);196pos = count;197return result;198}199200public int readNBytes(byte[] b, int off, int len) {201int n = read(b, off, len);202return n == -1 ? 0 : n;203}204205public synchronized long transferTo(OutputStream out) throws IOException {206int len = count - pos;207out.write(buf, pos, len);208pos = count;209return len;210}211212/**213* Skips {@code n} bytes of input from this input stream. Fewer214* bytes might be skipped if the end of the input stream is reached.215* The actual number {@code k}216* of bytes to be skipped is equal to the smaller217* of {@code n} and {@code count-pos}.218* The value {@code k} is added into {@code pos}219* and {@code k} is returned.220*221* @param n the number of bytes to be skipped.222* @return the actual number of bytes skipped.223*/224public synchronized long skip(long n) {225long k = count - pos;226if (n < k) {227k = n < 0 ? 0 : n;228}229230pos += k;231return k;232}233234/**235* Returns the number of remaining bytes that can be read (or skipped over)236* from this input stream.237* <p>238* The value returned is {@code count - pos},239* which is the number of bytes remaining to be read from the input buffer.240*241* @return the number of remaining bytes that can be read (or skipped242* over) from this input stream without blocking.243*/244public synchronized int available() {245return count - pos;246}247248/**249* Tests if this {@code InputStream} supports mark/reset. The250* {@code markSupported} method of {@code ByteArrayInputStream}251* always returns {@code true}.252*253* @since 1.1254*/255public boolean markSupported() {256return true;257}258259/**260* Set the current marked position in the stream.261* ByteArrayInputStream objects are marked at position zero by262* default when constructed. They may be marked at another263* position within the buffer by this method.264* <p>265* If no mark has been set, then the value of the mark is the266* offset passed to the constructor (or 0 if the offset was not267* supplied).268*269* <p> Note: The {@code readAheadLimit} for this class270* has no meaning.271*272* @since 1.1273*/274public void mark(int readAheadLimit) {275mark = pos;276}277278/**279* Resets the buffer to the marked position. The marked position280* is 0 unless another position was marked or an offset was specified281* in the constructor.282*/283public synchronized void reset() {284pos = mark;285}286287/**288* Closing a {@code ByteArrayInputStream} has no effect. The methods in289* this class can be called after the stream has been closed without290* generating an {@code IOException}.291*/292public void close() throws IOException {293}294295}296297298