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

com.cybermkd.upload.multipart.BufferedServletInputStream Maven / Gradle / Ivy

There is a newer version: 1.0.1.3
Show newest version
package com.cybermkd.upload.multipart;

import java.io.IOException;
import java.io.InputStream;

/**
 * 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.0, 2000/10/27, initial revision */ public class BufferedServletInputStream extends ServletInputStream { /** * input stream we are filtering */ private InputStream 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(InputStream in) { this.in = in; } /** * 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 scan. * @param pos position in byte array to scan from. * @param len maximum number of bytes to scan. * @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; } /** * 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. * * @throws 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. * @throws 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; } /** * 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. * @throws 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. * @throws 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