net.lightbody.bmp.proxy.jetty.http.nio.ByteBufferInputStream Maven / Gradle / Ivy
The newest version!
// ========================================================================
// $Id: ByteBufferInputStream.java,v 1.5 2005/08/13 00:01:26 gregwilkins Exp $
// Copyright 2003-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package net.lightbody.bmp.proxy.jetty.http.nio;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import net.lightbody.bmp.proxy.jetty.util.LazyList;
import org.apache.commons.logging.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
/* ------------------------------------------------------------------------------- */
/**
*
* @version $Revision: 1.5 $
* @author gregw
*/
public class ByteBufferInputStream extends InputStream
{
private static Log log= LogFactory.getLog(ByteBufferInputStream.class);
long _timeout=30000;
int _bufferSize;
ByteBuffer _buffer;
Object _buffers;
Object _recycle;
boolean _closed=false;
/* ------------------------------------------------------------------------------- */
/** Constructor.
*/
public ByteBufferInputStream(int bufferSize)
{
super();
_bufferSize=bufferSize;
}
/* ------------------------------------------------------------------------------- */
/** getSoTimeout.
* @return
*/
public long getTimeout()
{
return _timeout;
}
/* ------------------------------------------------------------------------------- */
/** setSoTimeout.
* @param l
*/
public void setTimeout(long l)
{
_timeout= l;
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#read()
*/
public synchronized int read() throws IOException
{
if (!waitForContent())
return -1;
return _buffer.get();
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#available()
*/
public synchronized int available() throws IOException
{
if (!waitForContent())
return -1;
return _buffer.remaining();
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#close()
*/
public synchronized void close() throws IOException
{
_closed=true;
this.notify();
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#mark(int)
*/
public synchronized void mark(int arg0)
{
// TODO Auto-generated method stub
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#markSupported()
*/
public synchronized boolean markSupported()
{
// TODO Auto-generated method stub
return false;
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#read(byte[], int, int)
*/
public synchronized int read(byte[] buf, int offset, int length)
throws IOException
{
if (!waitForContent())
return -1;
if (length>_buffer.remaining())
length=_buffer.remaining();
_buffer.get(buf, offset, length);
return length;
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#read(byte[])
*/
public synchronized int read(byte[] buf) throws IOException
{
if (!waitForContent())
return -1;
int length=buf.length;
if (length>_buffer.remaining())
length=_buffer.remaining();
_buffer.get(buf, 0, length);
return length;
}
/* ------------------------------------------------------------------------------- */
/*
* @see java.io.InputStream#reset()
*/
public synchronized void reset() throws IOException
{
// TODO Auto-generated method stub
super.reset();
}
/* ------------------------------------------------------------------------------- */
/**
* @see java.io.InputStream#skip(long)
*/
public long skip(long length) throws IOException
{
if (!waitForContent())
return -1;
if (length>_buffer.remaining())
length=_buffer.remaining();
_buffer.position((int)(_buffer.position()+length));
return length;
}
/* ------------------------------------------------------------------------------- */
public synchronized void write(ByteBuffer buffer)
{
if (buffer.hasRemaining())
{
_buffers=LazyList.add(_buffers,buffer);
this.notify();
}
else
recycle(buffer);
}
/* ------------------------------------------------------------------------------- */
private synchronized boolean waitForContent()
throws InterruptedIOException
{
if (_buffer!=null)
{
if (_buffer.hasRemaining())
return true;
// recycle buffer
recycle(_buffer);
_buffer=null;
}
while(!_closed && LazyList.size(_buffers)==0)
{
try
{
this.wait(_timeout);
}
catch(InterruptedException e)
{
log.debug(e);
throw new InterruptedIOException(e.toString());
}
}
if (_closed)
return false;
if (LazyList.size(_buffers)==0)
throw new SocketTimeoutException();
_buffer=(ByteBuffer)LazyList.get(_buffers, 0);
_buffers=LazyList.remove(_buffers, 0);
return true;
}
/* ------------------------------------------------------------------------------- */
/** Get a buffer to write to this InputStream.
* The buffer wll either be a new direct buffer or a recycled buffer.
*/
public synchronized ByteBuffer getBuffer()
{
ByteBuffer buf=null;
int s=LazyList.size(_recycle);
if (s>0)
{
s--;
buf=(ByteBuffer)LazyList.get(_recycle, s);
_recycle=LazyList.remove(_recycle,s);
buf.clear();
}
else
{
buf=ByteBuffer.allocateDirect(_bufferSize);
}
return buf;
}
/* ------------------------------------------------------------------------------- */
public synchronized void recycle(ByteBuffer buf)
{
_recycle=LazyList.add(_recycle,buf);
}
/* ------------------------------------------------------------------------------- */
public void destroy()
{
_buffer=null;
_buffers=null;
_recycle=null;
}
}