1 //  $Id: mmdb_io_stream.h $
2 //  =================================================================
3 //
4 //   CCP4 Coordinate Library: support of coordinate-related
5 //   functionality in protein crystallography applications.
6 //
7 //   Copyright (C) Eugene Krissinel 2000-2008.
8 //
9 //    This library is free software: you can redistribute it and/or
10 //    modify it under the terms of the GNU Lesser General Public
11 //    License version 3, modified in accordance with the provisions
12 //    of the license to address the requirements of UK law.
13 //
14 //    You should have received a copy of the modified GNU Lesser
15 //    General Public License along with this library. If not, copies
16 //    may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
17 //
18 //    This program is distributed in the hope that it will be useful,
19 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 //    GNU Lesser General Public License for more details.
22 //
23 //  =================================================================
24 //
25 //    11.09.13   <--  Date of Last Modification.
26 //                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 //  -----------------------------------------------------------------
28 //
29 //  **** Module  :  Stream <interface>
30 //       ~~~~~~~~~
31 //  **** Classes :  mmdb::io::Stream ( Basic Stream Class )
32 //       ~~~~~~~~~
33 //
34 //   (C) E. Krissinel 1995-2013
35 //
36 //  =================================================================
37 //
38 
39 #ifndef __MMDB_IO_Stream__
40 #define __MMDB_IO_Stream__
41 
42 #include "mmdb_io_file.h"
43 
44 //  *******************************************************************
45 
46 #ifndef __ClassMacros
47 
48 # define __ClassMacros
49 
50  //  A Class definition macros
51 # define DefineClass(ClassName)             \
52    class ClassName;                         \
53    typedef ClassName    * P##ClassName;     \
54    typedef ClassName    & R##ClassName;     \
55    typedef P##ClassName * PP##ClassName;    \
56    typedef P##ClassName & RP##ClassName;
57 
58  //  A Structure definition macros
59 # define DefineStructure(StructureName)             \
60    struct StructureName;                            \
61    typedef StructureName    * P##StructureName;     \
62    typedef StructureName    & R##StructureName;     \
63    typedef P##StructureName * PP##StructureName;    \
64    typedef P##StructureName & RP##StructureName;
65 
66 #endif
67 
68 
69 #define  DefineStreamFunctions(ClassName)                              \
70   extern void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ); \
71   extern void StreamRead  ( mmdb::io::RFile f, RP##ClassName Object );
72 
73 
74 #define  MakeStreamFunctions(ClassName)                                \
75   void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object )  {      \
76     StreamWrite_ ( f,(mmdb::io::RPStream)Object );                     \
77   }                                                                    \
78   mmdb::io::PStream StreamInit##ClassName ( mmdb::io::RPStream Object ) { \
79     return (mmdb::io::PStream)(new ClassName(Object));                 \
80   }                                                                    \
81   void StreamRead ( mmdb::io::RFile f, RP##ClassName Object )  {       \
82     StreamRead_ ( f,(mmdb::io::RPStream)Object,StreamInit##ClassName );\
83   }
84 
85 #define  DefineFactoryFunctions(ClassName)                             \
86   typedef P##ClassName      Make##ClassName();                         \
87   typedef Make##ClassName * PMake##ClassName;                          \
88   typedef P##ClassName  StreamMake##ClassName ( mmdb::io::RPStream Object ); \
89   P##ClassName  new##ClassName ();                                     \
90   P##ClassName  streamNew##ClassName ( mmdb::io::RPStream Object );    \
91   typedef StreamMake##ClassName * PStreamMake##ClassName;              \
92   extern void SetMakers##ClassName ( void * defMk, void * streamMk );  \
93   extern void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ); \
94   extern void StreamRead  ( mmdb::io::RFile f, RP##ClassName Object );
95 
96 
97 #define  MakeFactoryFunctions(ClassName)                               \
98   static PMake##ClassName       make##ClassName       = NULL;          \
99   static PStreamMake##ClassName streamMake##ClassName = NULL;          \
100   P##ClassName new##ClassName()  {                                     \
101     if (make##ClassName)  return (*make##ClassName)();                 \
102                     else  return new ClassName();                      \
103   }                                                                    \
104   P##ClassName streamNew##ClassName ( mmdb::io::RPStream Object )  {   \
105     if (streamMake##ClassName)                                         \
106           return (*streamMake##ClassName)(Object);                     \
107     else  return new ClassName(Object);                                \
108   }                                                                    \
109   void SetMakers##ClassName ( void * defMk, void * streamMk )  {       \
110     make##ClassName       = PMake##ClassName(defMk);                   \
111     streamMake##ClassName = PStreamMake##ClassName(streamMk);          \
112   }                                                                    \
113   void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object )  {      \
114     StreamWrite_ ( f,(mmdb::io::RPStream)Object );                     \
115   }                                                                    \
116   mmdb::io::PStream StreamInit##ClassName ( mmdb::io::RPStream Object ) { \
117     return (mmdb::io::PStream)(streamNew##ClassName(Object));          \
118   }                                                                    \
119   void StreamRead ( mmdb::io::RFile f, RP##ClassName Object )  {       \
120     StreamRead_ ( f,(mmdb::io::RPStream)Object,StreamInit##ClassName ); \
121   }
122 
123 namespace mmdb  {
124 
125   namespace io  {
126 
127     //  ==========================  Stream  ===========================
128 
129     //     Each streamable class should be derived from Stream
130     //  and have constructor Class(PStream & Object), which should
131     //  initialize all memory of the class, and virtual functions
132     //  read(..) and write(..) (see below). Constructor Class(PStream&)
133     //  must not touch the Object variable. This constructor is used
134     //  only once just before the read(..) function. It is assumed that
135     //  read(..)/write(..) functions of the Class provide storage/reading
136     //  of  all vital data. Function read(..) must read data in exactly
137     //  the same way as function write(..) stores it.
138     //     For using Class in streams, three following functions should
139     //  be supplied:
140     //
141     //     1.
142     //     void StreamWrite ( File & f, PClass & Object )  {
143     //       StreamWrite ( f,(PStream)Object );
144     //     }
145     //
146     //     2.
147     //     PStream ClassInit ( PStream & Object )  {
148     //       return (PStream)(new Class(Object));
149     //     }
150     //
151     //     3.
152     //     void StreamRead ( File & f, PClass & Object )  {
153     //       StreamRead_ ( f,(PStream)Object,ClassInit );
154     //     }
155     //
156     //    All these functions are automatically generated by macros
157     //  DefineStreamFunctions(Class) -- in the header -- and
158     //  MakeStreamFunctions(Class) -- in the implementation body. Note
159     //  that macro DefineClass(Class) should always be issued for
160     //  streamable classes prior to the stream-making macros. Then
161     //  Class may be streamed using functions #1 and #3.
162     //    StreamRead will return NULL for Object if it was not in
163     //  the stream. If Object existed before calling StreamRead(..)
164     //  but was not found in the stream, it will be disposed (NULL
165     //  assigned).
166 
167 
168     DefineClass(Stream);
169     DefineStreamFunctions(Stream);
170 
171     class Stream  {
172       public :
Stream()173         Stream            ()           {}
Stream(RPStream)174         Stream            ( RPStream ) {}
~Stream()175         virtual ~Stream   ()           {}
read(RFile)176         virtual void read  ( RFile )   {}
write(RFile)177         virtual void write ( RFile )   {}
178     };
179 
180 
181     typedef PStream InitStreamObject(RPStream Object);
182 
183     extern  void StreamRead_  ( RFile f, RPStream Object,
184                                          InitStreamObject Init );
185 
186     extern  void StreamWrite_ ( RFile f, RPStream Object );
187 
188 
189   }
190 
191 }
192 
193 #endif
194