com.day.io.file.SizedInputStream Maven / Gradle / Ivy
/**
* $Id: SizedInputStream.java 12345 2004-08-22 04:56:09Z fielding $
*
* Copyright 1997-2004 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.io.file;
import java.io.IOException;
import java.io.InputStream;
/**
* This is a stream that will only supply bytes up to a certain length - if its
* position goes above that, it will stop.
*
* This is useful to wrap ServletInputStreams. The ServletInputStream will block
* if you try to read content from it that isn't there, because it doesn't know
* whether the content hasn't arrived yet or whether the content has finished.
* So, one of these, initialized with the Content-length sent in the
* ServletInputStream's header, will stop it blocking, providing it's been sent
* with a correct content length.
*
* @version $Revision: 1.9 $, $Date: 2004-08-22 06:56:09 +0200 (Sun, 22 Aug 2004) $
* @author InigoSurguy
* @since antbear
*/
public class SizedInputStream extends InputStream {
/** the wrapped input stream */
private final InputStream in;
/** the max length to provide */
private final int max;
/** the number of bytes already returned */
private int pos = 0;
/** the marked position */
private int mark = -1;
/**
* Creates a new SizedInputStream
that wraps the given input
* stream and limits it to a certain size.
*
* @param in The wrapped input stream
* @param size The maximum number of bytes to return
*/
public SizedInputStream(InputStream in, int size) {
// Some badly designed methods - eg the servlet API - overload length
// such that "-1" means stream finished
this.max = size < 0 ? 0 : size;
this.in = in;
}
/**
* Calculates the number of bytes that are available to stream back.
* @return the number of bytes left
*/
private int bytesLeft() {
return max - pos;
}
/**
* @see InputStream#read()
*/
public int read() throws IOException {
if (pos==max) {
return -1;
}
int result = in.read();
pos++;
return result;
}
/**
* @see InputStream#read(byte[])
*/
public int read(byte[] b) throws IOException {
return this.read(b, 0, b.length);
}
/**
* @see InputStream#read(byte[], int, int)
*/
public int read(byte[] b, int off, int len) throws IOException {
if (pos>=max) {
return -1;
}
int maxRead = Math.min(len, bytesLeft());
int bytesRead = in.read(b, off, maxRead);
if (bytesRead==-1) {
return -1;
}
pos+=bytesRead;
return bytesRead;
}
/**
* @see InputStream#skip(long)
*/
public long skip(long n) throws IOException {
long skippedBytes = in.skip(Math.min(n, bytesLeft()));
pos+=skippedBytes;
return skippedBytes;
}
/**
* @see InputStream#available()
*/
public int available() throws IOException {
if (pos>=max) {
return 0;
}
return in.available();
}
/**
* @see InputStream#toString()
*/
public String toString() {
return in.toString();
}
/**
* @see InputStream#close()
*/
public void close() throws IOException {
in.close();
}
/**
* @see InputStream#reset()
*/
public synchronized void reset() throws IOException {
in.reset();
pos = mark;
}
/**
* @see InputStream#mark(int)
*/
public synchronized void mark(int readlimit) {
in.mark(readlimit);
mark = pos;
}
/**
* @see InputStream#markSupported()
*/
public boolean markSupported() {
return in.markSupported();
}
}