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

HTTPClient.BufferedInputStream Maven / Gradle / Ivy

Go to download

Modified version of HTTPClient used by The Grinder. The original can be found at http://www.innovation.ch/java/HTTPClient/.

There is a newer version: 3.11
Show newest version
/*
 * @(#)BufferedInputStream.java				0.3-3 06/05/2001
 *
 *  This file is part of the HTTPClient package
 *  Copyright (C) 1996-2001 Ronald Tschalär
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA 02111-1307, USA
 *
 *  For questions, suggestions, bug-reports, enhancement-requests etc.
 *  I may be contacted at:
 *
 *  [email protected]
 *
 *  The HTTPClient's home page is located at:
 *
 *  http://www.innovation.ch/java/HTTPClient/ 
 *
 */

package HTTPClient;

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

/**
 * This class is similar to java.io.BufferedInputStream, except that it fixes
 * certain bugs and provides support for finding multipart boundaries.
 *
 * 

Note: none of the methods here are synchronized because we assume the * caller is already taking care of that. * * @version 0.3-3 06/05/2001 * @author Ronald Tschalär */ class BufferedInputStream extends FilterInputStream { /** our read buffer */ private byte[] buffer = new byte[2000]; /** the next byte in the buffer at which to read */ private int pos = 0; /** the end of the valid data in the buffer */ private int end = 0; /** the current mark position, or -1 if none */ private int mark_pos = -1; /** * the large read threashhold: reads larger than this aren't buffered if * both the current buffer is empty and no mark has been set. This is just * an attempt to balance copying vs. multiple reads. */ private int lr_thrshld = 1500; /** * Create a new BufferedInputStream around the given input stream. * * @param stream the underlying input stream to use */ BufferedInputStream(InputStream stream) { super(stream); } /** * Read a single byte. * * @return the read byte, or -1 if the end of the stream has been reached * @exception IOException if thrown by the underlying stream */ public int read() throws IOException { if (pos >= end) fillBuff(); return (end > pos) ? (buffer[pos++] & 0xFF) : -1; } /** * Read a buffer full. * * @param buf the buffer to read into * @param off the offset within buf at which to start writing * @param len the number of bytes to read * @return the number of bytes read * @exception IOException if thrown by the underlying stream */ public int read(byte[] buf, int off, int len) throws IOException { if (len <= 0) return 0; // optimize for large reads if (pos >= end && len >= lr_thrshld && mark_pos < 0) return in.read(buf, off, len); if (pos >= end) fillBuff(); if (pos >= end) return -1; int left = end - pos; if (len > left) len = left; System.arraycopy(buffer, pos, buf, off, len); pos += len; return len; } /** * Skip the given number of bytes in the stream. * * @param n the number of bytes to skip * @return the actual number of bytes skipped * @exception IOException if thrown by the underlying stream */ public long skip(long n) throws IOException { if (n <= 0) return 0; int left = end - pos; if (n <= left) { pos += n; return n; } else { pos = end; return left + in.skip(n - left); } } /** * Fill buffer by reading from the underlying stream. This assumes the * current buffer is empty, i.e. pos == end. */ private final void fillBuff() throws IOException { if (mark_pos > 0) // keep the marked stuff around if possible { // only copy if we don't have any space left if (end >= buffer.length) { System.arraycopy(buffer, mark_pos, buffer, 0, end - mark_pos); pos = end - mark_pos; } } else if (mark_pos == 0 && end < buffer.length) ; // pos == end, so we just fill what's left else pos = 0; // try to fill complete buffer // make sure our state is consistent even if read() throws InterruptedIOException end = pos; int got = in.read(buffer, pos, buffer.length - pos); if (got > 0) end = pos + got; } /** * @return the number of bytes available for reading without blocking * @exception IOException if the buffer is empty and the underlying stream has been * closed */ public int available() throws IOException { int avail = end - pos; if (avail == 0) return in.available(); try { avail += in.available(); } catch (IOException ignored) { /* ignore this because we have something available */ } return avail; } /** * Mark the current read position so that we can start searching for the end boundary. */ void markForSearch() { mark_pos = pos; } /** * Figures out how many bytes past the end of the multipart we read. If we * found the end, it then resets the read pos to just past the end of the * boundary and unsets the mark; if not found, is sets the mark_pos back * enough from the current position so we can always be sure to find the * boundary. * * @param search the search string (end boundary) * @param search_cmp the compiled info of the search string * @return how many bytes past the end of the boundary we went; -1 if we * haven't gone passed it yet. */ int pastEnd(byte[] search, int[] search_cmp) { int idx = Util.findStr(search, search_cmp, buffer, mark_pos, pos); if (idx == -1) mark_pos = (pos > search.length) ? pos - search.length : 0; else { int eos = idx + search.length; idx = pos - eos; pos = eos; mark_pos = -1; } return idx; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy