📄 bufferedservicereader.java
字号:
/*
* @<#> BufferedServiceReader.java, version 0.0.1, 1/1/2001
*
* THIS PROGRAM IS FREE SOFTWARE; YOU CAN DISTRIBUTE IT AND/OR
* MODIFY IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE
* AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.
*
* THIS PROGRAM 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 GENERAL PUBLIC LICENSE FOR MORE DETAILS.
*
* Copyright (c) 2000 Wayne State University. All Rights Reserved.
*/
package naplet.serviceChannel;
import java.io.Reader;
import java.io.IOException;
import naplet.*;
import naplet.serviceChannel.*;
/**
* Buffered character-input stream from priviledged services to naplets.
*
* The class implements a buffered input stream. By setting up such an input
* stream, the priviledged services can read characters from the underlying
* ServiceReader without necessarily causing a call to the underlying system
* for each character read. The data is read from an internal buffer,
* and then the buffer got filled from the underlying stream if there are no
* valid characters in the buffer.
*
* @version 0.0.1, 1/1/2001
* @author C. Xu (czxu@yahoo.com)
*/
public class BufferedServiceReader extends Reader
{
protected ServiceReader in;
protected final int BUFFER_SIZE = 1024;
/**
* The internal buffer array where the data is stored.
*
*/
protected char[] buffer;
/**
* The index one greater than the index of the last valid character in
* the buffer. This is always in the range 0 through buf.length;
* elements buf[0] through buf[count - 1] contain buffered input
* data obtained from the underlying input stream.
*
*/
protected int count = 0;
/**
* The current position in the buffer. This is the index of the next
* character to be read from the buffer array. Its value is always in
* the range 0 through count. If it is less than count, then buf[pos]
* is the next character to be supplied as input; if it is equal to
* count, then the next read operation will require more characters to
* be read from the contained input stream
*
*/
protected int pos = 0;
/**
* Creates a <code>BufferedServiceReader</code> that uses a
* default-sized input buffer.
*
* @param in A ServiceReader
*
* @see naplet.ServiceReader
*/
public BufferedServiceReader( ServiceReader in )
{
this.in = in;
buffer = new char[BUFFER_SIZE];
}
/**
* Creates a <code>BufferedServiceReader</code> that uses an
* input buffer of the specified size.
*
* @param in A ServiceReader
* @param size Input-buffer size
*
* @exception IOException if an I/O error occurs.
* @exception IllegalArgumentException if size is <= 0
*
* @see naplet.ServiceReader
*/
public BufferedServiceReader( ServiceReader in, int size )
{
this.in = in;
if ( size <= 0 )
{
try
{
in.close( );
}
catch ( IOException e )
{
System.err.println( e.getMessage( ) );
}
throw new IllegalArgumentException( );
}
buffer = new char[size];
}
/**
* Fill the internal buffer by reading characters from the underlying
* input stream.
*
* @return the number of charaters read, or -1 if the end of the
* stream has been reached.
*
* @exception IOException if an I/O error occurs.
*/
private synchronized int fill( )
throws IOException
{
int rlen = in.read( buffer, count, buffer.length - count );
if ( rlen > 0 )
{
count += rlen;
}
return rlen;
}
/**
* Read a single character. This method will block until a character is
* available, an I/O error occurs, or the end of the stream is reached.
*
* @return the charater read, as an integer in the range 0 through
* 65535( 0x00-0xffff ), or -1 if the end of the stream has been
* reached.
* @exception IOException if an I/O error occurs.
*/
public int read( )
throws IOException
{
int ret;
synchronized ( this )
{
// No readable byte is available in the buffer, buffer
// needs to be refilled.
if ( pos >= count )
{
if ( count >= buffer.length )
{
pos = 0;
count = 0;
}
if ( fill( ) < 0 )
{
return -1;
}
}
ret = ( int ) buffer[pos++];
}
return ret;
}
/**
* Read characters into an array. This method will block until a
* character is available, an I/O error occurs, or the end of the
* stream is reached.
*
* @param b Destination buffer
* @param off Offset at which to start storing characters
* @param len Maximum number of characters to read
*
* @return the number of charaters read, or -1 if the end of the
* stream has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read( char[] b, int off, int len )
throws IOException
{
if ( ( off < 0 ) || ( off >= b.length ) || ( len < 0 )
|| ( ( off + len ) > b.length ) || ( ( off + len ) < 0 ) )
{
throw new IndexOutOfBoundsException( );
}
else if ( len == 0 )
{
return 0;
}
int rlen;
synchronized ( this )
{
// If no readable byte is available in the buffer, read bytes
// directly from the underlying input stream, meanwhile fill
// the buffer. Otherwise, read the bytes from the buffer and
// refill the buffer.
rlen = count - pos;
if ( rlen >= len )
{
rlen = len;
System.arraycopy( buffer, pos, b, off, len );
pos += len;
}
else
{
if ( rlen > 0 )
{
System.arraycopy( buffer, pos, b, off, rlen );
pos = count;
rlen += in.read( b, off + rlen, len - rlen );
}
else
{
rlen = in.read( b, off, len );
}
if ( count == buffer.length )
{
count = 0;
pos = 0;
}
}
fill( );
}
return rlen;
}
/**
* Close this buffered input stream and releases any system resources
* associated with the stream.
*
* @exception IOException if an I/O error occurs.
*/
public void close( )
throws IOException
{
synchronized ( this )
{
pos = 0;
count = 0;
in.close( );
}
}
/**
* Tell whether this stream is ready to be read.
*
* @return true if the next read is guaranteed not to block for input,
* false otherwise. Note that returning false does not guarantee
* that the next read will block.
*
* @exception IOException if an I/O error occurs
*/
public boolean ready( )
throws IOException
{
return in.ready( );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -