/* $Id$ */ package ibis.ipl.impl.nio; import ibis.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ReadOnlyBufferException; import java.nio.channels.ReadableByteChannel; /** * Reads data from a channel. */ public final class ChannelDissipator extends DataInputStream { public static final int SIZEOF_BYTE = 1; public static final int SIZEOF_CHAR = 2; public static final int SIZEOF_SHORT = 2; public static final int SIZEOF_INT = 4; public static final int SIZEOF_LONG = 8; public static final int SIZEOF_FLOAT = 4; public static final int SIZEOF_DOUBLE = 8; static final int BUFFER_SIZE = 1024; private ReadableByteChannel channel; private ByteBuffer buffer; private long count = 0; public ChannelDissipator(ReadableByteChannel channel) { buffer = ByteBuffer.allocate(BUFFER_SIZE).order(ByteOrder.BIG_ENDIAN); // make the buffer apear empty buffer.limit(0); this.channel = channel; } public int bufferSize() { return BUFFER_SIZE; } public int available() throws IOException { return buffer.remaining(); } public void close() throws IOException { channel.close(); } public long bytesRead() { return count; } public void resetBytesRead() { count = 0; } private void readAtLeast(int minimum) throws IOException { int count; buffer.compact(); while (buffer.position() < minimum) { count = channel.read(buffer); if (count == -1) { throw new IOException("eos read on reading from channel"); } this.count += count; } buffer.flip(); } public boolean readBoolean() throws IOException { return (readByte() == ((byte) 1)); } public byte readByte() throws IOException { try { return buffer.get(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_BYTE); return buffer.get(); } } public int read() throws IOException { try { return readByte() & 0377; } catch (EOFException e) { return -1; } } public char readChar() throws IOException { try { return buffer.getChar(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_CHAR); return buffer.getChar(); } } public short readShort() throws IOException { try { return buffer.getShort(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_SHORT); return buffer.getShort(); } } public int readInt() throws IOException { try { return buffer.getInt(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_INT); return buffer.getInt(); } } public long readLong() throws IOException { try { return buffer.getLong(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_LONG); return buffer.getLong(); } } public float readFloat() throws IOException { try { return buffer.getFloat(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_FLOAT); return buffer.getFloat(); } } public double readDouble() throws IOException { try { return buffer.getDouble(); } catch (BufferUnderflowException e) { readAtLeast(SIZEOF_DOUBLE); return buffer.getDouble(); } } public void readArray(boolean[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readBoolean(); } } public void readArray(byte[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readByte(); } } public void readArray(char[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readChar(); } } public void readArray(short[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readShort(); } } public void readArray(int[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readInt(); } } public void readArray(long[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readLong(); } } public void readArray(float[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readFloat(); } } public void readArray(double[] destination, int offset, int length) throws IOException { for (int i = offset; i < (offset + length); i++) { destination[i] = readDouble(); } } public void readByteBuffer(ByteBuffer value) throws IOException, ReadOnlyBufferException { for (int i = value.position(); i < value.limit(); i++) { value.put(readByte()); } } }