wiki:uka.transport/Marshal

Implementing marshaling methods

Marshaling a transportable object is done by the marshal stream calling the object's marshal(MarshalStream) method. A reference to the marshal stream is provided as argument. The object itself is responsible for writing its fields to the stream.

Since class TParam contains fields of basic type and reference type, the marshaling process is split into two phases:

Values of basic types

Values of basic type are marshaled efficiently by writing them in blocks of known size. The size in bytes of the data block written to the MarshalStream has to be announced in advance. Marshaling of basic typed fields must adhere to the following procedure:

  1. Announce the size of the data block to be written. Method reserve(int) of MarshalStream is called with the size in bytes as argument. The number of bytes marshaled in one chunk may not exceed TransportConstants.REQUEST_MAX bytes.
  2. Look up the stream buffer and the current position within the buffer.
  3. Insert the field values into the byte array buffer. Class BasicIO provides a variety of static methods to insert values of basic type into an array of bytes. It also manages the actual position within the buffer.
  4. Commit the write. Method deliver(int) commits the write of the data to the stream. The value of the parameter must match the value passed to method reserve() in the first step.

Values of reference type

After all basic typed values of a class have been written, references to other objects are marshaled. For each reference method writeObject(Object) of the MarshalStream is called.

To reuse the serialization code in subclasses, it is recommended to split it into three methods:

  • marshal(MarshalStream) is declared in interface Transportable and is called directly by the marshal stream. This method is responsible for announcing the correct size of primitive typed fields and calls the other two methods.
  • marshalPrimitives(byte[], int) is used to insert all fields of basic type into the byte array buffer at the current position.
  • marshalReferences(MarshalStream) marshals all fields of reference type to the stream.

The following example shows marshaling methods and declarations that enable correct marshaling of objects of class TParam.

//
// Marshaling: Methods and declarations for class TParam
//
protected static final int _SIZE = 
    uka.transport.BasicIO.SIZEOF_float + 
    uka.transport.BasicIO.SIZEOF_int;

public void marshal(uka.transport.MarshalStream _stream)
    throws java.io.IOException
{
    _stream.reserve(_SIZE);
    byte[] _buffer = _stream.getBuffer();
    int    _pos    = _stream.getPosition();
    marshalPrimitives(_buffer, _pos);
    _stream.deliver(_SIZE);
    marshalReferences(_stream);
}

protected void marshalPrimitives(byte[] _buffer, int _pos)
    throws java.io.IOException
{
    _pos = uka.transport.BasicIO.insert(_buffer, _pos, floatValue);
    _pos = uka.transport.BasicIO.insert(_buffer, _pos, intValue);
}

protected void marshalReferences(uka.transport.MarshalStream _stream)
    throws java.io.IOException
{
    _stream.writeObject(objectReference);
}
Last modified 12 years ago Last modified on Aug 22, 2005 9:08:24 AM