/* * Player Java Client 3 - XdrUnion.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.io.InvalidClassException; /** * The abstract base class <code>XdrUnion</code> helps (de-)serializing * polymorphic classes. This class should not be confused with C unions in * general. Instead <code>XdrUnion</code> is an object-oriented construct * which helps in deploying polymorphism. For examples on how to use this, * please take a look at the "ACPLTea Java Library" package, which is also * available from <code>www.acplt.org/ks</code>. As a sidenote, the * serialization scheme implemented by <code>XdrUnion</code> is only a question * of getting used to it: after serializing the type code of the polymorphic * class, the variant part is serialized first before the common part. This * behaviour stems from the ACPLT C++ Communication Library and has been * retained for compatibility reasons. As it doesn't hurt, you won't mind * anyway. * * <p>To use polymorphism with XDR streams, you'll have to derive your own base * class (let's call it <code>foo</code> from <code>XdrUnion</code> * and implement the two methods * {@link #xdrEncodeCommon(XdrEncodingStream)} and * {@link #xdrDecodeCommon(XdrDecodingStream)}. Do not overwrite * the methods xdrEncode and xdrDecode! * * <p>Then, in your <code>foo</code>-derived classes, like <code>bar</code> * and <code>baz</code>, implement the other two methods * {@link #xdrEncodeVariant(XdrEncodingStream)} and * {@link #xdrDecodeVariant(XdrDecodingStream)}. In addition, implement * {@link #getXdrTypeCode} to return an int, uniquely identifying your * class. Note that this identifier only needs to be unique within the scope * of your <code>foo</code> class. * * @version $Revision$ $Date$ $State$ $Locker$ * @author Harald Albrecht */ public abstract class XdrUnion implements XdrAble { /** * Returns the so-called type code which identifies a derived class when * encoded or decoded. Note that the type code is not globally unique, but * rather it is only unique within the derived classes of a direct descend * of XdrUnion. If <code>foo</code> is derived from <code>XdrUnion</code> * and <code>foo</code> is the base class for <code>bar</code> and * <code>baz</code>, then the type code needs only be unique between * <code>bar</code> and <code>baz</code>. * * @return Type code identifying an object's class when encoding or * decoding the object into or from a XDR stream. */ public abstract int getXdrTypeCode(); /** * Encodes -- that is: serializes -- an object into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { // // For historial reasons (read: "for dumb and pure idiotic reasons") // and compatibility with the ACPLT/KS C++ Communication Library we // encode/decode the variant part *first* before encoding/decoding // the common part. // xdr.xdrEncodeInt(getXdrTypeCode()); xdrEncodeVariant(xdr); xdrEncodeCommon(xdr); } /** * Decodes -- that is: deserializes -- an object from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Make sure that when deserializing this object's state that // the stream provides state information indeed intended for this // particular class. // int xdrTypeCode = xdr.xdrDecodeInt(); if ( xdrTypeCode != getXdrTypeCode() ) { throw(new InvalidClassException(this.getClass().getName(), "non-matching XDR type code received.")); } // // For historial reasons (read: "for dumb and pure idiotic reasons") // and compatibility with the ACPLT/KS C++ Communication Library we // encode/decode the variant part *first* before encoding/decoding // the common part. // xdrDecodeVariant(xdr); xdrDecodeCommon(xdr); } /** * Encodes -- that is: serializes -- the common part of an object into * a XDR stream in compliance to RFC 1832. Note that the common part is * deserialized after the variant part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeCommon(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes -- that is: deserializes -- the common part of an object from * a XDR stream in compliance to RFC 1832. Note that the common part is * deserialized after the variant part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecodeCommon(XdrDecodingStream xdr) throws OncRpcException, IOException; /** * Encodes -- that is: serializes -- the variant part of an object into * a XDR stream in compliance to RFC 1832. Note that the variant part is * deserialized before the common part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeVariant(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes -- that is: deserializes -- the variant part of an object from * a XDR stream in compliance to RFC 1832. Note that the variant part is * deserialized before the common part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecodeVariant(XdrDecodingStream xdr) throws OncRpcException, IOException; } // End of XdrUnion.java