/* $Id$ */
package ibis.ipl;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A message used to write data from a {@link SendPort} to one or more
* {@link ReceivePort}s.
* <p>
* A <code>WriteMessage</code> is obtained from a {@link SendPort} through
* the {@link SendPort#newMessage SendPort.newMessage} method.
* At most one <code>WriteMessage</code> is alive at one time for a given
* </code>SendPort</code>.
* When a message is alive and a new message is requested, the requester
* is blocked until the live message is finished.
* <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 can be
* read by {@link ReadMessage#readObject}. Likewise, an
* array written with the {@link WriteMessage#writeByteBuffer} method can be read
* by {@link ReadMessage#readObject} (resulting in a byte array), and also by the
* {@link ReadMessage#readArray(byte[])} method.
* <strong>
* In contrast, an array written with
* {@link #writeObject writeObject}
* cannot be read with <code>readArray</code>, because
* {@link #writeObject writeObject} does duplicate detection,
* and may have written only a handle.
* </strong>
* However, an array written with {@link #writeArray(byte[])} can be
* read with {@link ReadMessage#readByteBuffer(ByteBuffer)}.
* <p>
* The {@link #writeObject(Object)} and {@link #writeString(String)} methods
* do duplicate checks if the underlying serialization stream is an object
* serialization stream: if the object was already written to this
* message, a handle for this object is written instead of the object itself.
*<p>
* When the port type has the {@link PortType#CONNECTION_ONE_TO_MANY}
* or {@link PortType#CONNECTION_MANY_TO_MANY} capability set,
* no exceptions are thrown by write methods in the write message.
* Instead, the exception may be passed on to the <code>lostConnection</code>
* upcall, in case a {@link SendPortDisconnectUpcall} is registered.
* This allows a multicast to continue to the other destinations.
* Ultimately, the {@link WriteMessage#finish() finish} method will
* throw an exception.
* <p>
* Data may be streamed, so the user is not allowed to change the data
* pushed into this message.
* It is only safe to touch the data after it has actually been
* sent, which can be ensured by either calling {@link #flush},
* {@link WriteMessage#finish()} or {@link #reset},
* or a {@link #send} followed by a corresponding {@link #sync}.
*/
public interface WriteMessage {
/**
* Starts sending the message to all {@link ibis.ipl.ReceivePort
* ReceivePorts} its {@link ibis.ipl.SendPort} is connected to.
* Data may be streamed, so the user is not allowed to change the data
* pushed into this message, as the send is NON-blocking.
* It is only safe to touch the data after it has actually been
* sent, which can be ensured by either calling {@link #finish()} or
* {@link #reset}, or a {@link #sync} corresponding to this send.
* The <code>send</code> method returns a ticket, which can be used
* as a parameter to the {@link #sync} method, which will block until
* the data corresponding to this ticket can be used again.
* @return
* a ticket.
* @exception IOException
* an error occurred
**/
public int send() throws IOException;
/**
* Blocks until the data of the <code>send</code> which returned
* the <code>ticket</code> parameter may be used again.
* It also synchronizes with respect to all sends before that.
* If <code>ticket</code> does not correspond to any <code>send</code>,
* it blocks until all outstanding sends have been processed.
* @param ticket
* the ticket number.
* @exception IOException
* an error occurred
*/
public void sync(int ticket) throws IOException;
/**
* Blocks until all objects written to this message can be
* used again.
* @exception IOException
* an error occurred
*/
public void flush() throws IOException;
/**
* Resets the state of any objects already written to the stream.
* This means that the WriteMessage "forgets" which objects already
* have been written with it.
* @exception IOException
* an error occurred
*/
public void reset() throws IOException;
/**
* If needed, send, and then block until the entire message has been sent
* and clear the message. The number of bytes written in this message
* is returned.
* <strong>
* Even for multicast messages, the size only counts once.
* </strong>
* @return
* the number of bytes written in 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>WriteMessage</code> methods has thrown an IOException.
* It implies a {@link #finish()}.
* @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.
*
* <strong>
* Even for multicast messages, the size only counts once.
* </strong>
* @return
* the number of bytes written to this message.
* @exception IOException
* an error occurred.
*/
public long bytesWritten() throws IOException;
/**
* Returns the maximum number of bytes that will fit into this message.
*
* @return
* the maximum number of bytes that will fit into this message or
* -1 when the message size is unlimited
* @exception IOException
* an error occurred.
*/
public int capacity() throws IOException;
/**
* Returns the remaining number of bytes that can be written into this
* message.
*
* @return
* the remaining number of bytes that can be written into this
* message or -1 when the message size is unlimited
* @exception IOException
* an error occurred.
*/
public int remaining() throws IOException;
/**
* Returns the {@link SendPort} of this <code>WriteMessage</code>.
* @return
* the {@link SendPort} of this <code>WriteMessage</code>.
*/
public SendPort localPort();
/**
* Writes a boolean value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the boolean value to write.
* @exception IOException
* an error occurred
*/
public void writeBoolean(boolean value) throws IOException;
/**
* Writes a byte value to the message.
* @param value
* the byte value to write.
* @exception IOException
* an error occurred
*/
public void writeByte(byte value) throws IOException;
/**
* Writes a char value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the char value to write.
* @exception IOException
* an error occurred
*/
public void writeChar(char value) throws IOException;
/**
* Writes a short value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the short value to write.
* @exception IOException
* an error occurred
*/
public void writeShort(short value) throws IOException;
/**
* Writes a int value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the int value to write.
* @exception IOException
* an error occurred
*/
public void writeInt(int value) throws IOException;
/**
* Writes a long value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the long value to write.
* @exception IOException
* an error occurred
*/
public void writeLong(long value) throws IOException;
/**
* Writes a float value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the float value to write.
* @exception IOException
* an error occurred
*/
public void writeFloat(float value) throws IOException;
/**
* Writes a double value to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* @param value
* the double value to write.
* @exception IOException
* an error occurred
*/
public void writeDouble(double value) throws IOException;
/**
* Writes a <code>String</code> to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* If the underlying serialization stream is an object serialization
* stream, a duplicate check for this <code>String</code> object
* is performed: if the object was already written to this
* message, a handle for this object is written instead of
* the object itself.
* @param value
* the string to write.
* @exception IOException
* an error occurred
*/
public void writeString(String value) throws IOException;
/**
* Writes a <code>Serializable</code> object to the message.
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
* A duplicate check for this <code>String</code> object
* is performed: if the object was already written to this
* message, a handle for this object is written instead of
* the object itself.
* @param value
* the object value to write.
* @exception IOException
* an error occurred
*/
public void writeObject(Object value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
**/
public void writeArray(boolean[] value) throws IOException;
/**
* Writes an array to the message.
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(byte[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(char[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(short[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(int[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(long[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(float[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(double[] value) throws IOException;
/**
* Writes an array to the message.
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
* No duplicate check is performed for this array!
* This method is just a shortcut for doing:
* <code>writeArray(val, 0, val.length);</code>
* @param value
* the array to be written.
* @exception IOException
* an error occurred
*/
public void writeArray(Object[] value) throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(boolean[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(byte[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(char[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(short[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(int[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(long[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(float[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream can only do byte serialization.
* (See {@link PortType#SERIALIZATION_BYTE}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(double[] value, int offset, int length)
throws IOException;
/**
* Writes a slice of an array. The slice starts at offset <code>off</code>.
* This method throws an IOException if the underlying serialization
* stream cannot do object serialization.
* (See {@link PortType#SERIALIZATION_OBJECT}).
* No duplicate check is performed for this array!
* @param value
* the array to be written
* @param offset
* offset in the array
* @param length
* the number of elements to be written
* @exception IOException
* an error occurred
*/
public void writeArray(Object[] value, int offset, int length)
throws IOException;
/**
* Writes 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
*/
public void writeByteBuffer(ByteBuffer value)
throws IOException;
}