All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.acplt.oncrpc.package.html Maven / Gradle / Ivy

There is a newer version: 1.1.6
Show newest version


ONC/RPC for Java package



Sun's ONC/RPC Remote Procedure Call mechanism.

This package implements Sun's ONC/RPC Remote Procedure Call specification (see RFC 1831, RFC 1832, RFC 1833).

Functionality currently supported:

  • RPC calls over TCP/IP as well as UDP/IP.
  • RPC client functionality.
  • RPC server functionality (see package org.acplt.oncrpc.server).
  • Querying the ONC/RPC portmapper.
  • jrpcgen-utility for converting x-files into Java classes.
  • Support for authentication types AUTH_NONE, AUTH_UNIX and AUTH_SHORT on both the client and the server side.

To manually convert x-files into serializable Java classes, first map the primitive rpcgen data types (and thus the data types described in RFC 1832 to some extend) onto Java's primitive data types. The following table should help you doing this.

rpcgen / RFC 1832Java
char
(used as character)
8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
byte = xdr.xdrDecodeByte()
unsigned char
(used as character)
8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
byte = xdr.xdrDecodeByte()
char
(used as 8 bit quantitiy)
8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
byte = xdr.xdrDecodeByte()
unsigned char
(used as 8 bit quantitiy)
8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
byte = xdr.xdrDecodeByte()
shortplatform dependent short16 bits xdr.xdrEncodeShort(short)
short = xdr.xdrDecodeShort()
unsigned shortplatform dependent short16 bits xdr.xdrEncodeShort(short)
short = xdr.xdrDecodeShort()
int32 bits int32 bits xdr.xdrEncodeInt(int)
int = xdr.xdrDecodeInt()
unsigned int32 bits int32 bits xdr.xdrEncodeInt(int)
int = xdr.xdrDecodeInt()
hyper64 bits long64 bits xdr.xdrEncodeLong(long)
long = xdr.xdrDecodeLong()
unsigned hyper64 bits long64 bits xdr.xdrEncodeLong(long)
long = xdr.xdrDecodeLong()
enum32 bits int32 bits xdr.xdrEncodeInt(int)
int = xdr.xdrDecodeInt()
bool  boolean  xdr.xdrEncodeBoolean(boolean)
boolean = xdr.xdrDecodeBoolean()
float32 bits float32 bits xdr.xdrEncodeFloat(float)
float = xdr.xdrDecodeFloat()
double64 bits double64 bits xdr.xdrEncodeDouble(double)
double = xdr.xdrDecodeDouble()
quadruple128 bits n/a   
opaque[n]exactly n octets byte[]n bytes xdr.xdrEncodeOpaque(byte[])
byte[] = xdr.xdrDecodeOpaque(n)
opaque<n>4 bytes size followed by
at most n octets
byte[]?? bytes xdr.xdrEncodeDynamicOpaque(byte[])
byte[] = xdr.xdrDecodeDynamicOpaque()
opaque<>4 bytes size followed by
?? octets
byte[]?? bytes xdr.xdrEncodeDynamicOpaque(byte[])
byte[] = xdr.xdrDecodeDynamicOpaque()
string<n>4 bytes size followed by
at most n octets
String?? bytes xdr.xdrEncodeString(String)
String = xdr.xdrDecodeString()
string<>4 bytes size followed by
?? octets
String?? bytes xdr.xdrEncodeString(String)
String = xdr.xdrDecodeString()
void0 bits XdrVoid  xdrvoid.xdrEncode(xdr)
xdrvoid.xdrDecode(xdr)

The Remote Tea library also provides method to (de-) serialize vector data types of variable length, as shown below. To (de-) derialize fixed-size vectors, use the ...FixedVector() variants and supply the protocol-defined size of the vector -- see the next table but one.

rpcgen / RFC 1832Java
opaque<>4 bytes size followed by
?? octets
byte[] xdr.xdrEncodeDynamicOpaque(byte[])
byte[] = xdr.xdrDecodeDynamicOpaque()
char<>
char short<>
4 bytes size followed by
?? chars
byte[] xdr.xdrEncodeByteVector(byte[])
byte[] = xdr.xdrDecodeByteVector()
short<>
unsigned short<>
4 bytes size followed by
?? shorts
short[] xdr.xdrEncodeShortVector(short[])
short[] = xdr.xdrDecodeShortVector()
int<>
unsigned int<>
4 bytes size followed by
?? ints
int[] xdr.xdrEncodeIntVector(int[])
int[] = xdr.xdrDecodeIntVector()
long<>
unsigned long<>
4 bytes size followed by
?? longs
int[] xdr.xdrEncodeIntVector(int[])
int[] = xdr.xdrDecodeIntVector()
hyper<>
unsigned hyper<>
4 bytes size followed by
?? hypers
long[] xdr.xdrEncodeLongVector(long[])
long[] = xdr.xdrDecodeLongVector()
enum<>4 bytes size followed by
?? enums
int[] xdr.xdrEncodeIntVector(int[])
int[] = xdr.xdrDecodeIntVector()
bool<>4 bytes size followed by
?? bools
boolean[] xdr.xdrEncodeBooleanVector(boolean[])
boolean[] = xdr.xdrDecodeBooleanVector()
float<>4 bytes size followed by
?? floats
float[] xdr.xdrEncodeFloatVector(float[])
float[] = xdr.xdrDecodeFloatVector()
double<>4 bytes size followed by
?? doubles
double[] xdr.xdrEncodeDoubleVector(double[])
double[] = xdr.xdrDecodeDoubleVector()

And now for (de-) serializing fixed-size vectors:

rpcgen / RFC 1832Java
char[n]
char short[n]
4 bytes size followed by
n chars
byte[] xdr.xdrEncodeByteFixedVector(byte[], int n)
byte[] = xdr.xdrDecodeByteFixedVector(int n)
short[n]
unsigned short[n]
4 bytes size followed by
n shorts
short[] xdr.xdrEncodeShortFixedVector(short[], int n)
short[] = xdr.xdrDecodeShortFixedVector(int n)
int[n]
unsigned int[n]
4 bytes size followed by
n ints
int[] xdr.xdrEncodeIntFixedVector(int[], int n)
int[] = xdr.xdrDecodeIntFixedVector(int n)
long[n]
unsigned long[n]
4 bytes size followed by
n longs
int[] xdr.xdrEncodeIntFixedVector(int[], int n)
int[] = xdr.xdrDecodeIntFixedVector(int n)
hyper[n]
unsigned hyper[n]
4 bytes size followed by
n hypers
long[] xdr.xdrEncodeLongFixedVector(long[], int n)
long[] = xdr.xdrDecodeLongFixedVector(int n)
enum[n]4 bytes size followed by
n enums
int[] xdr.xdrEncodeIntFixedVector(int[], int n)
int[] = xdr.xdrDecodeIntFixedVector(int n)
bool[n]4 bytes size followed by
n bools
boolean[] xdr.xdrEncodeBooleanFixedVector(boolean[], int n)
boolean[] = xdr.xdrDecodeBooleanFixedVector(int n)
float[n]4 bytes size followed by
n floats
float[] xdr.xdrEncodeFloatFixedVector(float[], int n)
float[] = xdr.xdrDecodeFloatFixedVector(int n)
double[n]4 bytes size followed by
n doubles
double[] xdr.xdrEncodeDoubleFixedVector(double[], int n)
double[] = xdr.xdrDecodeDoubleFixedVector(int n)

For every structure you encounter in a .x file, write a Java class, which implements the XdrAble interface. For instance, taking this snippet from a rpcgen source file...

struct foo {
    int bar;
    float baz;
    struct foo *next;
};

...struct foo is translated into Java ONC/RPC babble as:

class foo implements XdrAble {
   // members of foo structure
   public int bar;
   public float baz;
   public foo next;

   // serialize / encode foo
    public void xdrEncode(XdrEncodingStream xdr)
           throws OncRpcException, IOException {
        xdr.xdrEncodeInt(bar);
        xdr.xdrEncodeFloat(baz);
        if ( next == null ) {
            xdr.xdrEncodeBoolean(false);
        } else {
            xdr.xdrEncodeBoolean(true);
            next.xdrEncode(xdr);
        }
    }

    // deserialize / decode foo
    public void xdrDecode(XdrDecodingStream xdr)
           throws OncRpcException, IOException {
        bar = xdr.xdrDecodeInt();
        baz = xdr.xdrDecodeFloat();
        if ( !xdr.xdrDecodeBoolean() ) {
            next = null;
        } else {
            next = new foo();
            next.xdrDecode(xdr);
        }
    }
}

The previous example also shows how to deal with pointers (eeek!) in .x files. The are simply transformed into references -- quite a difference, really.

Tanslating a descriminated union is typically done the simple and silly way. Silly, because unions can not really be represented in the Java language. You need to transform them into a class (structure) instead, and this will lead to a rather ugly form.

union foo switch (FOOTYPE type) {
    case BAR_CLASS:
        bar u_bar;
    case BAZ_CLASS:
        baz u_baz;
}
should become
class foo implements XdrAble {
    // descriminant value
    public int type;
    // arm declarations
    public bar u_bar;
    public baz u_baz;

    // descriminant-arm values
    public static int BAR_CLASS = 1;
    public static int BAZ_CLASS = 2;

    // serialize / encode foo
    public void xdrEncode(XdrEncodingStream xdr)
           throws OncRpcException, IOException {
        xdr.xdrEncodeInt(type);
        switch ( type ) {
        case BAR_CLASS:
            u_bar.xdrEncode(xdr); break;
        case BAZ_CLASS:
            u_baz.xdrEncode(xdr); break;
        }
    }

    // deserialize / decode foo
    public void xdrDecode(XdrDecodingStream xdr)
           throws OncRpcException, IOException {
        type = xdr.xdrDecodeInt();
        switch ( type ) {
        case BAR_CLASS:
            u_bar = new bar(); u_bar.xdrDecode(xdr); break;
        case BAZ_CLASS:
            u_baz = new bar(); u_bar.xdrDecode(xdr); break;
        }
    }
}

You can also take advantage of polymorphism when translating descriminated unions into a class hierarchy. You should then write an abstract base class with only one static member function capable of constructing the appropriate instance from the XDR stream. The tricky part about this is getting the descriminant value into the stream or out of it without having to duplicate the decoding code into the constructor. With the skeleton below you should be able to do this easily, but you should remember to never recycle an object reference and never deserialize the state of the object a second time from a XDR stream!

abstract class foobase implements XdrAble {
    // construct a bar, baz,... class from XDR stream
    public static foobase xdrNew(XdrDecodingStream xdr)
           throws OncRpcException, IOException {
        foobase obj = null;
        switch ( xdr.xdrDecodeInt() ) {
        case BAR_CLASS:
            obj = new bar(); break;
        case BAZ_CLASS:
            obj = new baz(); break;
        }
        obj.xdrDecode(xdr);
        return obj;
    }

    public abstract void xdrEncode(XdrEncodingStream xdr)
           throws OncRpcException, IOException;
    public abstract void xdrDecode(XdrDecodingStream xdr)
           throws OncRpcException, IOException;

    // descriminant values
    public static int BAR_CLASS = 1;
    public static int BAZ_CLASS = 2;
}

class bar extends foobase {
    public void xdrEncode(XdrEncodingStream xdr)
           throws OncRpcException, IOException {
        // encode your members here...
        // dont forget to encode the descriminant value
        xdr.xdrEncodeInt(BAR_CLASS);
        xdr.xdrEncodeFloat(noah);
    }
    public void xdrDecode(XdrDecodingStream xdr)
           throws OncRpcException, IOException {
        // decode your members here...
        // but *NEVER* decode the descriminant value
        noah = xdr.xdrDecodeFloat();
    }
}

This package is part of the ACPLT/KS ACPLTea Java Library package.

(c) 1999, 2006 Harald Albrecht.
(c) 1999, 2002 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

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 LICENSE.txt for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.