/* 
 * PVM++ - A C++ library for easy use of PVM
 * Copyright (C) 1997-2001 Sebastian Wilhelmi; University of Karlsruhe
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __PVM_CUSTOM_HH__
#define __PVM_CUSTOM_HH__

namespace Pvm
{

  /** Base class for classes with non-standard packing and unpacking.
      
      This class is the base class for all data, you want to transmit,
      for which there are no standard Register ()-Calls (see
      \Ref{Struct}). For all types, that can be registered via
      Register()-Calls, there are functions called Pack
      (const Type &) and Unpack (type), which can be used in the
      Pack () and UnPack ()-methods of Custom. You can also use
      this mechanism, if you want to transmit data "compressed". For
      example you could have a huge array, that is mostly used with
      little data:
      
      \begin{verbatim}
      struct MyHugeArray : public Pvm::Custom
      {
        int Size;
        int Huge[100000];
        void Pack () const
          {
            Pvm::Pack (Size);
            for (int i = 0; i < Size; ++i)
              Pvm::Pack (Huge[i]);
          }
        void UnPack ()
          {
            Pvm::Unpack (Size);
            for (int i = 0; i < Size; ++i)
              Pvm::Unpack (Huge[i]);
          }
      };

      struct Test : public Pvm::Struct
      {
        PvmSetStructId (43); 
        PvmRegistration ()
        {
          Pvm::Register (Data);
        }
        MyHugeArray Data;
      };

      int 
      main ()
      {
        Test A;
        A.Data.Size = 3;
        A.Data.Huge[ 0 ] = 4;
        A.Data.Huge[ 1 ] = 8;
        A.Data.Huge[ 2 ] = 16;
        A.Send (Pvm::Pvm ().I ().Parent ()); // Only 4 ints are sent, not 100001 !
      }
      \end{verbatim} */

  class Custom
  {
  public:
    /** must be overridden with a function, that packs all relevant data
	of the derived class. */
    virtual void Pack () const = 0;
    
    /** must be overridden with a function, that unpacks all relevant
	data of the derived class. */
    virtual void UnPack () = 0;
    virtual ~Custom ();
  };
  
} // namespace Pvm

#endif /* __PVM_CUSTOM_HH__ */
