//  $Id: mmdb_io_stream.cpp $
//  =================================================================
//
//   CCP4 Coordinate Library: support of coordinate-related
//   functionality in protein crystallography applications.
//
//   Copyright (C) Eugene Krissinel 2000-2013.
//
//    This library is free software: you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License version 3, modified in accordance with the provisions
//    of the license to address the requirements of UK law.
//
//    You should have received a copy of the modified GNU Lesser
//    General Public License along with this library. If not, copies
//    may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
//    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 Lesser General Public License for more details.
//
//  =================================================================
//
//    11.09.13   <--  Date of Last Modification.
//                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  -----------------------------------------------------------------
//
//  **** Module  :  Stream_ <interface>
//       ~~~~~~~~~
//  **** Classes :  mmdb::io::Stream  ( Basic Stream Class )
//       ~~~~~~~~~
//
//   (C) E. Krissinel 1995-2013
//
//  =================================================================
//

#include "mmdb_io_stream.h"

namespace mmdb  {

  namespace io  {

    //  ==========================  CStream  ===========================

    //     Each streamable class should be derived from Stream
    //  and have constructor Class(PStream & Object), which should
    //  initialize all memory of the class, and virtual functions
    //  read(..) and write(..) (see below). Constructor Class(PStream&)
    //  must not touch the Object variable. This constructor is used
    //  only once just before read(..) function. It is assumed that
    //  read/write functions of Class provide storage/reading of
    //  all vital data. Function read(..) must read data in exactly
    //  the same way as function write(..) stores it.
    //     For using Class in streams, three following functions should
    //  be supplied:
    //
    //     1.
    //     void StreamWrite ( RFile f, RPClass Object )  {
    //       StreamWrite ( f,(PStream)PClass );
    //     }
    //
    //     2.
    //     PCStream ClassInit ( RPStream Object )  {
    //       return (PStream)(new Class(Object));
    //     }
    //
    //     3.
    //     void StreamRead ( RFile f, RPClass Object )  {
    //       StreamRead_ ( f,(PStream)Object,ClassInit );
    //     }
    //
    //    All these functions are automatically generated by macros
    //  DefineStreamFunctions(CClass) -- in the header -- and
    //  MakeStreamFunctions(CClass) -- in the implementation body.
    //  Then CClass may be streamed in/out using functions #1 and #3.
    //    StreamRead will return NULL for Object if it was not
    //  in the stream. If Object existed before StreamRead(..) but
    //  was not found in the stream, it will be disposed.

    void StreamRead_ ( RFile f, RPStream Object,
                       InitStreamObject Init )  {
    int i;
      f.ReadInt ( &i );
      if (i)  {
        if (!Object)
          Object = Init(Object); //Object = new CStream ( Object );
        Object->read ( f );
      } else  {
        if (Object)  delete Object;
        Object = NULL;
      }
    }

    void StreamWrite_ ( RFile f, RPStream Object )  {
    int i;
      if (Object)  {
        i = 1;
        f.WriteInt ( &i );
        Object->write ( f );
      } else  {
        i = 0;
        f.WriteInt ( &i );
      }
    }

    MakeStreamFunctions(Stream)

  }

}
