/* $Id$ */
package ibis.ipl;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
/**
* The Ibis abstraction for data to be read.
* <p>
* A <code>ReadMessage</code> is obtained from a
* {@link ibis.ipl.ReceivePort receiveport}, either
* by means of an upcall, or by means of an explicit receive, which is
* accomplished by call to {@link ibis.ipl.ReceivePort#receive() receive}.
* A {@link ibis.ipl.ReceivePort receiveport} can be configured to generate
* upcalls or to support blocking receive, but NOT both!
* At most one <code>ReadMessage</code> is alive at one time for a given
* </code>ReceivePort</code>.
* <p>
* For all read methods in this class, the invariant is that the reads must
* match the writes one by one. An exception to this rule is that an
* array written with any of the <code>writeArray</code> methods of
* {@link WriteMessage} can be read by {@link #readObject}. Likewise, an
* array written with the {@link WriteMessage#writeByteBuffer} method can be read
* by {@link #readObject} (resulting in a byte array), and also by the
* {@link #readArray(byte[])} method.
* <strong>
* In contrast, an array written with
* {@link WriteMessage#writeObject writeObject}
* cannot be read with <code>readArray</code>, because
* {@link WriteMessage#writeObject writeObject} does duplicate detection,
* and may have written only a handle.
* </strong>
* However, an array written with {@link WriteMessage#writeArray(byte[])} can be
* read with {@link #readByteBuffer(ByteBuffer)}.
**/
public interface ReadMessage {
/** The first sequence number when communication is numbered. */
public static final long INITIAL_SEQNO = 1;
/**
* The <code>finish</code> operation is used to indicate that the
* reader is done with the message.
* After the finish, no more bytes can be read from the message.
* The thread reading the message (can be an upcall) is NOT
* allowed to block when a message is alive but not finished.
* Only after the finish is called can the thread that holds the
* message block.
* The finish operation must always be called when blocking receive
* is used. When upcalls are used, the finish can be avoided when the
* user is sure that the upcall never blocks or waits for a message
* to arrive. In that case, the message is automatically finished when
* the upcall terminates. This is much more efficient, because in this way,
* the runtime system can reuse the upcall thread!
*
* @return
* the number of bytes read from this message.
* @exception IOException
* an error occurred.
**/
public long finish() throws IOException;
/**
* This method can be used to inform Ibis that one of the
* <code>ReadMessage</code> methods has thrown an IOException.
* It implies a {@link #finish()}.
* In a message upcall, the alternative way to do this is to have
* the upcall throw the exception.
* @param exception
* the exception that was thrown.
*/
public void finish(IOException exception);
/**
* Returns the number of bytes read from this message.
* Note that for streaming implementations (i.e., messages with an unlimited
* capacity) this number may not be exact because of intermediate buffering.
*
* @return
* the number of bytes read sofar from this message.
* @exception IOException
* an error occurred.
*/
public long bytesRead() throws IOException;
/**
* Returns the size of this message in bytes.
*
* @return
* the size of this message in byte or -1 if the size is unknown or
* unlimited.
* @exception IOException
* an error occurred.
*/
public int size() throws IOException;
/**
* Returns the remaining number bytes available for reading in this message.
*
* @return
* the number remaining bytes available for reading in this message
* or -1 if the message size is unknown or unlimited.
* @exception IOException
* an error occurred.
*/
public int remaining() throws IOException;
/**
* Returns the {@link ibis.ipl.ReceivePort receiveport} of this
* <code>ReadMessage</code>.
*
* @return
* the {@link ibis.ipl.ReceivePort receiveport} of this
* <code>ReadMessage</code>.
*/
public ReceivePort localPort();
/**
* Returns the sequence number of this message.
* @return
* the sequence number for this message.
* @exception IbisConfigurationException
* is thrown if the port type of the receive port does not have
* the {@link PortType#COMMUNICATION_NUMBERED} capability.
*/
public long sequenceNumber();
/**
* Returns the {@link ibis.ipl.SendPortIdentifier sendport identifier}
* of the sender of this message.
*
* @return
* the id of the sender of this message.
*/
public SendPortIdentifier origin();
/**
* Reads a boolean value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public boolean readBoolean() throws IOException;
/**
* Reads a byte value from the message.
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public byte readByte() throws IOException;
/**
* Reads a char value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public char readChar() throws IOException;
/**
* Reads a short value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public short readShort() throws IOException;
/**
* Reads an int value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public int readInt() throws IOException;
/**
* Reads a long value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public long readLong() throws IOException;
/**
* Reads a float value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public float readFloat() throws IOException;
/**
* Reads a double value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public double readDouble() throws IOException;
/**
* Reads a <code>String</code> value from the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
*/
public String readString() throws IOException;
/**
* Reads an <code>Object</code> value from the message.
* Note: implementations should take care that an array, written with one
* of the writeArray variants, can be read with <code>readObject</code>.
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
*
* @return
* the value read.
* @exception IOException
* an error occurred
* @exception ClassNotFoundException
* is thrown when an object arrives of a class that cannot be
* loaded locally.
*/
public Object readObject() throws IOException, ClassNotFoundException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(boolean[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(byte[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(char[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(short[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(int[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(long[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(float[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
*/
public void readArray(double[] destination) throws IOException;
/**
* Receives an array in place. This method is a shortcut for
* <code>readArray(destination, 0, destination.length);</code>
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
*
* @param destination
* where the received array is stored.
* @exception IOException
* is thrown when an IO error occurs.
* @exception ClassNotFoundException
* when an object arrives of a class that cannot be loaded locally.
*/
public void readArray(Object[] destination) throws IOException,
ClassNotFoundException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(boolean[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(byte[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(char[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(short[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(int[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(long[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(float[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
*/
public void readArray(double[] destination, int offset, int size)
throws IOException;
/**
* Reads a slice of an array in place.
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
*
* @param destination
* array in which the slice is stored
* @param offset
* offset where the slice starts
* @param size
* length of the slice (the number of elements)
* @exception IOException
* is thrown on an IO error.
* @exception ClassNotFoundException
* when an object arrives of a class that cannot be loaded locally.
*/
public void readArray(Object[] destination, int offset, int size)
throws IOException, ClassNotFoundException;
/**
* Reads into the contents of the byte buffer (between its current position and its
* limit). This method is allowed for all serialization types, even
* {@link PortType#SERIALIZATION_BYTE}.
* @param value
* the byte buffer from which data is to be written
* @exception IOException
* an error occurred
* @exception ReadOnlyBufferException
* is thrown when the buffer is read-only.
*/
public void readByteBuffer(ByteBuffer value)
throws IOException, ReadOnlyBufferException;
}