/*
* Player Java Client 3 - XdrEncodingStream.java
* Copyright (C) 2002-2006 Radu Bogdan Rusu, Maxim Batalin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
*
*/
/*
* Copyright (c) 1999, 2000
* Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen
* D-52064 Aachen, Germany.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package javaclient3.xdr;
import java.io.IOException;
import java.net.InetAddress;
/**
* Defines the abstract base class for all encoding XDR streams. An encoding
* XDR stream receives data in the form of Java data types and writes it to
* a data sink (for instance, network or memory buffer) in the
* platform-independent XDR format.
*
* <p>Derived classes need to implement the {@link #xdrEncodeInt(int)},
* {@link #xdrEncodeOpaque(byte[])} and
* {@link #xdrEncodeOpaque(byte[], int, int)} methods to make this complete
* mess workable.
*
* @version $Revision$ $Date$ $State$ $Locker$
* @author Harald Albrecht
*/
public abstract class XdrEncodingStream {
/**
* Begins encoding a new XDR record. This typically involves resetting this
* encoding XDR stream back into a known state.
*
* @param receiverAddress Indicates the receiver of the XDR data. This can
* be <code>null</code> for XDR streams connected permanently to a
* receiver (like in case of TCP/IP based XDR streams).
* @param receiverPort Port number of the receiver.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public void beginEncoding(InetAddress receiverAddress, int receiverPort)
throws OncRpcException, IOException {
}
/**
* Flushes this encoding XDR stream and forces any buffered output bytes
* to be written out. The general contract of <code>endEncoding</code> is that
* calling it is an indication that the current record is finished and any
* bytes previously encoded should immediately be written to their intended
* destination.
*
* <p>The <code>endEncoding</code> method of <code>XdrEncodingStream</code>
* does nothing.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public void endEncoding()
throws OncRpcException, IOException {
}
/**
* Closes this encoding XDR stream and releases any system resources
* associated with this stream. The general contract of <code>close</code>
* is that it closes the encoding XDR stream. A closed XDR stream cannot
* perform encoding operations and cannot be reopened.
*
* <p>The <code>close</code> method of <code>XdrEncodingStream</code>
* does nothing.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public void close()
throws OncRpcException, IOException {
}
/**
* Encodes (aka "serializes") a "XDR int" value and writes it down a
* XDR stream. A XDR int is 32 bits wide -- the same width Java's "int"
* data type has. This method is one of the basic methods all other
* methods can rely on. Because it's so basic, derived classes have to
* implement it.
*
* @param value The int value to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public abstract void xdrEncodeInt(int value)
throws OncRpcException, IOException;
/**
* Encodes (aka "serializes") a XDR opaque value, which is represented
* by a vector of byte values, and starts at <code>offset</code> with a
* length of <code>length</code>. Only the opaque value is encoded, but
* no length indication is preceeding the opaque value, so the receiver
* has to know how long the opaque value will be. The encoded data is
* always padded to be a multiple of four. If the given length is not a
* multiple of four, zero bytes will be used for padding.
*
* <p>Derived classes must ensure that the proper semantic is maintained.
*
* @param value The opaque value to be encoded in the form of a series of
* bytes.
* @param offset Start offset in the data.
* @param length the number of bytes to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public abstract void xdrEncodeOpaque(byte [] value, int offset, int length)
throws OncRpcException, IOException;
/**
* Encodes (aka "serializes") a XDR opaque value, which is represented
* by a vector of byte values. The length of the opaque value is written
* to the XDR stream, so the receiver does not need to know
* the exact length in advance. The encoded data is always padded to be
* a multiple of four to maintain XDR alignment.
*
* @param value The opaque value to be encoded in the form of a series of
* bytes.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeDynamicOpaque(byte [] value)
throws OncRpcException, IOException {
xdrEncodeInt(value.length);
xdrEncodeOpaque(value);
}
/**
* Encodes (aka "serializes") a XDR opaque value, which is represented
* by a vector of byte values. Only the opaque value is encoded, but
* no length indication is preceeding the opaque value, so the receiver
* has to know how long the opaque value will be. The encoded data is
* always padded to be a multiple of four. If the length of the given byte
* vector is not a multiple of four, zero bytes will be used for padding.
*
* @param value The opaque value to be encoded in the form of a series of
* bytes.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeOpaque(byte [] value)
throws OncRpcException, IOException {
xdrEncodeOpaque(value, 0, value.length);
}
/**
* Encodes (aka "serializes") a XDR opaque value, which is represented
* by a vector of byte values. Only the opaque value is encoded, but
* no length indication is preceeding the opaque value, so the receiver
* has to know how long the opaque value will be. The encoded data is
* always padded to be a multiple of four. If the length of the given byte
* vector is not a multiple of four, zero bytes will be used for padding.
*
* @param value The opaque value to be encoded in the form of a series of
* bytes.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeOpaque(byte [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
xdrEncodeOpaque(value, 0, value.length);
}
/**
* Encodes (aka "serializes") a vector of bytes, which is nothing more
* than a series of octets (or 8 bits wide bytes), each packed into its
* very own 4 bytes (XDR int). Byte vectors are encoded together with a
* preceeding length value. This way the receiver doesn't need to know
* the length of the vector in advance.
*
* @param value Byte vector to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeByteVector(byte [] value)
throws OncRpcException, IOException {
int length = value.length; // well, silly optimizations appear here...
xdrEncodeInt(length);
if ( length != 0 ) {
//
// For speed reasons, we do sign extension here, but the higher bits
// will be removed again when deserializing.
//
for ( int i = 0; i < length; ++i ) {
xdrEncodeInt((int) value[i]);
}
}
}
/**
* Encodes (aka "serializes") a vector of bytes, which is nothing more
* than a series of octets (or 8 bits wide bytes), each packed into its
* very own 4 bytes (XDR int).
*
* @param value Byte vector to encode.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeByteFixedVector(byte [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
if ( length != 0 ) {
//
// For speed reasons, we do sign extension here, but the higher bits
// will be removed again when deserializing.
//
for ( int i = 0; i < length; ++i ) {
xdrEncodeInt((int) value[i]);
}
}
}
/**
* Encodes (aka "serializes") a byte and write it down this XDR stream.
*
* @param value Byte value to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeByte(byte value)
throws OncRpcException, IOException {
//
// For speed reasons, we do sign extension here, but the higher bits
// will be removed again when deserializing.
//
xdrEncodeInt((int) value);
}
/**
* Encodes (aka "serializes") a short (which is a 16 bits wide quantity)
* and write it down this XDR stream.
*
* @param value Short value to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeShort(short value)
throws OncRpcException, IOException {
xdrEncodeInt((int) value);
}
/**
* Encodes (aka "serializes") a long (which is called a "hyper" in XDR
* babble and is 64 bits wide) and write it down this XDR stream.
*
* @param value Long value to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeLong(long value)
throws OncRpcException, IOException {
//
// Just encode the long (which is called a "hyper" in XDR babble) as
// two ints in network order, that is: big endian with the high int
// comming first.
//
xdrEncodeInt((int)(value >>> 32));
xdrEncodeInt((int)(value & 0xFFFFFFFF));
}
/**
* Encodes (aka "serializes") a float (which is a 32 bits wide floating
* point quantity) and write it down this XDR stream.
*
* @param value Float value to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeFloat(float value)
throws OncRpcException, IOException {
xdrEncodeInt(Float.floatToIntBits(value));
}
/**
* Encodes (aka "serializes") a double (which is a 64 bits wide floating
* point quantity) and write it down this XDR stream.
*
* @param value Double value to encode.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeDouble(double value)
throws OncRpcException, IOException {
xdrEncodeLong(Double.doubleToLongBits(value));
}
/**
* Encodes (aka "serializes") a boolean and writes it down this XDR stream.
*
* @param value Boolean value to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeBoolean(boolean value)
throws OncRpcException, IOException {
xdrEncodeInt(value ? 1 : 0);
}
/**
* Encodes (aka "serializes") a string and writes it down this XDR stream.
*
* @param value String value to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeString(String value)
throws OncRpcException, IOException {
if ( characterEncoding != null ) {
xdrEncodeDynamicOpaque(value.getBytes(characterEncoding));
} else {
xdrEncodeDynamicOpaque(value.getBytes());
}
}
/**
* Encodes (aka "serializes") a vector of short integers and writes it down
* this XDR stream.
*
* @param value short vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeShortVector(short [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeShort(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of short integers and writes it down
* this XDR stream.
*
* @param value short vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeShortFixedVector(short [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeShort(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of ints and writes it down
* this XDR stream.
*
* @param value int vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeIntVector(int [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeInt(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of ints and writes it down
* this XDR stream.
*
* @param value int vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeIntFixedVector(int [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeInt(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of long integers and writes it down
* this XDR stream.
*
* @param value long vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeLongVector(long [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeLong(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of long integers and writes it down
* this XDR stream.
*
* @param value long vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeLongFixedVector(long [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeLong(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of floats and writes it down
* this XDR stream.
*
* @param value float vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeFloatVector(float [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeFloat(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of floats and writes it down
* this XDR stream.
*
* @param value float vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeFloatFixedVector(float [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeFloat(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of doubles and writes it down
* this XDR stream.
*
* @param value double vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeDoubleVector(double [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeDouble(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of doubles and writes it down
* this XDR stream.
*
* @param value double vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeDoubleFixedVector(double [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeDouble(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of booleans and writes it down
* this XDR stream.
*
* @param value long vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeBooleanVector(boolean [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeBoolean(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of booleans and writes it down
* this XDR stream.
*
* @param value long vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeBooleanFixedVector(boolean [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeBoolean(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of strings and writes it down
* this XDR stream.
*
* @param value String vector to be encoded.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
*/
public final void xdrEncodeStringVector(String [] value)
throws OncRpcException, IOException {
int size = value.length;
xdrEncodeInt(size);
for ( int i = 0; i < size; i++ ) {
xdrEncodeString(value[i]);
}
}
/**
* Encodes (aka "serializes") a vector of strings and writes it down
* this XDR stream.
*
* @param value String vector to be encoded.
* @param length of vector to write. This parameter is used as a sanity
* check.
*
* @throws OncRpcException if an ONC/RPC error occurs.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the length of the vector does not
* match the specified length.
*/
public final void xdrEncodeStringFixedVector(String [] value, int length)
throws OncRpcException, IOException {
if ( value.length != length ) {
throw(new IllegalArgumentException("array size does not match protocol specification"));
}
for ( int i = 0; i < length; i++ ) {
xdrEncodeString(value[i]);
}
}
/**
* Set the character encoding for serializing strings.
*
* @param characterEncoding the encoding to use for serializing strings.
* If <code>null</code>, the system's default encoding is to be used.
*/
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}
/**
* Get the character encoding for serializing strings.
*
* @return the encoding currently used for serializing strings.
* If <code>null</code>, then the system's default encoding is used.
*/
public String getCharacterEncoding() {
return characterEncoding;
}
/**
* Encoding to use when serializing strings or <code>null</code> if
* the system's default encoding should be used.
*/
private String characterEncoding = null;
}
// End of XdrEncodingStream.java