📄 limitinputstream.java
字号:
/*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*
* $Id: LimitInputStream.java,v 1.1 2002/06/03 20:48:20 bondolo Exp $
*/
package net.jxta.util;
import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;
/**
* Implements a bounds on the number of bytes which may be read from an
* InputStream.
**/
public class LimitInputStream extends java.io.FilterInputStream {
private transient long limit;
private transient long read;
private transient long mark;
private transient boolean fatalUnderflow;
private transient boolean alreadycounting;
/** Creates a new instance of LimitInputStream */
public LimitInputStream( InputStream in, long limit ) {
this( in, limit, false );
}
/** Creates a new instance of LimitInputStream */
public LimitInputStream( InputStream in, long limit, boolean underflowThrows ) {
super(in);
this.limit = limit;
this.mark = -1;
this.read = 0;
this.fatalUnderflow = underflowThrows;
this.alreadycounting = false;
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* This
* method simply performs <code>in.close()</code>.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public void close() throws IOException {
super.close();
in = null;
}
/** Returns the number of bytes that can be read from this input
* stream without blocking.
* <p>
* This method
* simply performs <code>in.available(n)</code> and
* returns the result.
*
* @return the number of bytes that can be read from the input stream
* without blocking.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int available() throws IOException {
return (int) Math.min( super.available(), (limit - read) );
}
/** Marks the current position in this input stream. A subsequent
* call to the <code>reset</code> method repositions this stream at
* the last marked position so that subsequent reads re-read the same bytes.
* <p>
* The <code>readlimit</code> argument tells this input stream to
* allow that many bytes to be read before the mark position gets
* invalidated.
* <p>
* This method simply performs <code>in.mark(readlimit)</code>.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.FilterInputStream#in
* @see java.io.FilterInputStream#reset()
*/
public void mark(int readlimit) {
super.mark( readlimit );
mark = read;
}
/** Repositions this stream to the position at the time the
* <code>mark</code> method was last called on this input stream.
* <p>
* This method
* simply performs <code>in.reset()</code>.
* <p>
* Stream marks are intended to be used in
* situations where you need to read ahead a little to see what's in
* the stream. Often this is most easily done by invoking some
* general parser. If the stream is of the type handled by the
* parse, it just chugs along happily. If the stream is not of
* that type, the parser should toss an exception when it fails.
* If this happens within readlimit bytes, it allows the outer
* code to reset the stream and try another parser.
*
* @exception IOException if the stream has not been marked or if the
* mark has been invalidated.
* @see java.io.FilterInputStream#in
* @see java.io.FilterInputStream#mark(int)
*/
public void reset() throws IOException {
if( -1 == mark )
throw new IOException( "reset() without mark(), or I dont know where mark is" );
super.reset();
read = mark;
}
/** Skips over and discards <code>n</code> bytes of data from the
* input stream. The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly <code>0</code>. The actual number of bytes skipped is
* returned.
* <p>
* This method
* simply performs <code>in.skip(n)</code>.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if an I/O error occurs.
*/
public synchronized long skip(long n) throws IOException {
long skipLen = Math.min( n, (limit - read) );
boolean wascounting = alreadycounting;
alreadycounting = true;
long result = super.skip( skipLen );
alreadycounting = wascounting;
if( (-1 != result) && !alreadycounting )
read += result;
return result;
}
/** Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
* <p>
* This method
* simply performs <code>in.read()</code> and returns the result.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public synchronized int read() throws IOException {
if ( read >= limit )
return -1;
boolean wascounting = alreadycounting;
alreadycounting = true;
int result = super.read();
alreadycounting = wascounting;
if( (-1 != result) && !alreadycounting ) {
read++;
} else {
if ( fatalUnderflow && (read != limit) )
throw new IOException( "Underflow in read, stream EOFed at " + read + " before limit of " + limit );
}
return result;
}
/** Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. This method blocks until some input is
* available.
* <p>
* This method simply performs <code>in.read(b, off, len)</code>
* and returns the result.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public synchronized int read(byte[] b, int off, int len) throws IOException {
if( read >= limit )
return -1;
boolean wascounting = alreadycounting;
alreadycounting = true;
int readLen = (int) Math.min( len, limit - read );
int result = super.read( b, off, readLen );
alreadycounting = wascounting;
if( (-1 != result) && !alreadycounting )
read += result;
else {
if ( fatalUnderflow && (read != limit) )
throw new IOException( "Underflow in read, stream EOFed at " + read + " before limit of " + limit );
}
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -