All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.silentgo.servlet.oreilly.multipart.BufferedServletInputStream Maven / Gradle / Ivy

There is a newer version: 0.0.49
Show newest version
// Copyright (C) 1999-2001 by Jason Hunter .
// All rights reserved.  Use of this class is limited.
// Please see the LICENSE for more information.
 
package com.silentgo.servlet.oreilly.multipart;

import java.io.IOException;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;

/**
 * A BufferedServletInputStream wraps a 
 * ServletInputStream in order to provide input buffering and to 
 * avoid calling the the readLine method of the wrapped 
 * ServletInputStream.
 * 

* This is necessary because some servlet containers rely on the default * implementation of the readLine method provided by the Servlet * API classes, which is very slow. Tomcat 3.2, Tomcat 3.1, the JSWDK 1.0 web * server and the JSDK2.1 web server are all known to need this class for * performance reasons. *

* Also, it may be used to work around a bug in the Servlet API 2.0 * implementation of readLine which contains a bug that causes * ArrayIndexOutOfBoundsExceptions under certain conditions. * Apache JServ is known to suffer from this bug. * * @author Geoff Soutter * @version 1.1, 2001/05/21, removed block of commented out code * @version 1.0, 2000/10/27, initial revision */ public class BufferedServletInputStream extends ServletInputStream { /** input stream we are filtering */ private ServletInputStream in; /** our buffer */ private byte[] buf = new byte[64*1024]; // 64k /** number of bytes we've read into the buffer */ private int count; /** current position in the buffer */ private int pos; /** * Creates a BufferedServletInputStream that wraps the provided * ServletInputStream. * * @param in a servlet input stream. */ public BufferedServletInputStream(ServletInputStream in) { this.in = in; } /** * Fill up our buffer from the underlying input stream. Users of this * method must ensure that they use all characters in the buffer before * calling this method. * * @exception IOException if an I/O error occurs. */ private void fill() throws IOException { int i = in.read(buf, 0, buf.length); if (i > 0) { pos = 0; count = i; } } /** * Implement buffering on top of the readLine method of * the wrapped ServletInputStream. * * @param b an array of bytes into which data is read. * @param off an integer specifying the character at which * this method begins reading. * @param len an integer specifying the maximum number of * bytes to read. * @return an integer specifying the actual number of bytes * read, or -1 if the end of the stream is reached. * @exception IOException if an I/O error occurs. */ public int readLine(byte b[], int off, int len) throws IOException { int total = 0; if (len == 0) { return 0; } int avail = count - pos; if (avail <= 0) { fill(); avail = count - pos; if (avail <= 0) { return -1; } } int copy = Math.min(len, avail); int eol = findeol(buf, pos, copy); if (eol != -1) { copy = eol; } System.arraycopy(buf, pos, b, off, copy); pos += copy; total += copy; while (total < len && eol == -1) { fill(); avail = count - pos; if(avail <= 0) { return total; } copy = Math.min(len - total, avail); eol = findeol(buf, pos, copy); if (eol != -1) { copy = eol; } System.arraycopy(buf, pos, b, off + total, copy); pos += copy; total += copy; } return total; } @Override public boolean isFinished() { return true; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { } /** * Attempt to find the '\n' end of line marker as defined in the comment of * the readLine method of ServletInputStream. * * @param b byte array to search. * @param pos position in byte array to search from. * @param len maximum number of bytes to search. * * @return the number of bytes including the \n, or -1 if none found. */ private static int findeol(byte b[], int pos, int len) { int end = pos + len; int i = pos; while (i < end) { if (b[i++] == '\n') { return i - pos; } } return -1; } /** * Implement buffering on top of the read method of * the wrapped ServletInputStream. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public int read() throws IOException { if (count <= pos) { fill(); if (count <= pos) { return -1; } } return buf[pos++] & 0xff; } /** * Implement buffering on top of the read method of * the wrapped ServletInputStream. * * @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 * -1 if there is no more data because the end * of the stream has been reached. * @exception IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { int total = 0; while (total < len) { int avail = count - pos; if (avail <= 0) { fill(); avail = count - pos; if(avail <= 0) { if (total > 0) return total; else return -1; } } int copy = Math.min(len - total, avail); System.arraycopy(buf, pos, b, off + total, copy); pos += copy; total += copy; } return total; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy