package org.jboss.pitbull.internal.nio.socket;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.TimeUnit;
/**
* A utility class containing static methods to support channel usage.
*
* @apiviz.exclude
*/
public final class Channels
{
/**
* Simple utility method to execute a blocking write on a byte channel. The method blocks until the bytes in the
* buffer have been fully written.
*
* @param channel the channel to write on
* @param buffer the data to write
* @param <C> the channel type
* @return the number of bytes written
* @throws java.io.IOException if an I/O exception occurs
* @since 1.2
*/
public static int writeBlocking(SocketChannel channel, ByteBuffer buffer) throws IOException
{
int t = 0;
while (buffer.hasRemaining())
{
final int res = channel.write(buffer);
if (res == 0)
{
SelectorUtil.awaitWritable(channel);
}
else
{
t += res;
}
}
return t;
}
/**
* Simple utility method to execute a blocking write on a byte channel with a timeout. The method blocks until
* either the bytes in the buffer have been fully written, or the timeout expires, whichever comes first.
*
* @param channel the channel to write on
* @param buffer the data to write
* @param time the amount of time to wait
* @param unit the unit of time to wait
* @param <C> the channel type
* @return the number of bytes written
* @throws java.io.IOException if an I/O exception occurs
* @since 1.2
*/
public static int writeBlocking(SocketChannel channel, ByteBuffer buffer, long time, TimeUnit unit) throws IOException
{
long remaining = unit.toMillis(time);
long now = System.currentTimeMillis();
int t = 0;
while (buffer.hasRemaining() && remaining > 0L)
{
int res = channel.write(buffer);
if (res == 0)
{
SelectorUtil.awaitWritable(channel, remaining, TimeUnit.MILLISECONDS);
}
else
{
t += res;
}
remaining -= Math.max(-now + (now = System.currentTimeMillis()), 0L);
}
return t;
}
/**
* Simple utility method to execute a blocking read on a readable byte channel. This method blocks until the
* channel is readable, and then the message is read.
*
* @param channel the channel to read from
* @param buffer the buffer into which bytes are to be transferred
* @param <C> the channel type
* @return the number of bytes read
* @throws java.io.IOException if an I/O exception occurs
* @since 1.2
*/
public static int readBlocking(SocketChannel channel, ByteBuffer buffer) throws IOException
{
int res;
while ((res = channel.read(buffer)) == 0 && buffer.hasRemaining())
{
SelectorUtil.awaitReadable(channel);
}
return res;
}
/**
* Simple utility method to execute a blocking read on a readable byte channel with a timeout. This method blocks until the
* channel is readable, and then the message is read.
*
* @param channel the channel to read from
* @param buffer the buffer into which bytes are to be transferred
* @param time the amount of time to wait
* @param unit the unit of time to wait
* @param <C> the channel type
* @return the number of bytes read
* @throws java.io.IOException if an I/O exception occurs
* @since 1.2
*/
public static int readBlocking(SocketChannel channel, ByteBuffer buffer, long time, TimeUnit unit) throws IOException
{
int res = channel.read(buffer);
if (res == 0 && buffer.hasRemaining())
{
SelectorUtil.awaitReadable(channel, time, unit);
return channel.read(buffer);
}
else
{
return res;
}
}
}