Merge release-5-0 into master
[alexxy/gromacs.git] / src / gromacs / fileio / gmxfio_xdr.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #include "config.h"
38
39 #include <errno.h>
40 #include <stdio.h>
41 #include <string.h>
42 #ifdef HAVE_IO_H
43 #include <io.h>
44 #endif
45
46 #include "gromacs/utility/fatalerror.h"
47 #include "macros.h"
48 #include "gromacs/utility/smalloc.h"
49 #include "gromacs/utility/futil.h"
50 #include "filenm.h"
51 #include "gmxfio.h"
52 #include "md5.h"
53
54 #include "gmxfio_int.h"
55
56 /* This is the part that reads xdr files.  */
57
58
59 /* file type functions */
60 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
61                            const char *desc, const char *srcfile, int line);
62 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
63                             const char *desc, const char *srcfile, int line);
64
65
66 const t_iotype xdr_iotype = {do_xdrread, do_xdrwrite};
67
68
69 #ifdef USE_XDR
70
71 static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
72                        const char *desc, const char *srcfile, int line)
73 {
74     unsigned char   ucdum, *ucptr;
75     bool_t          res = 0;
76     float           fvec[DIM];
77     double          dvec[DIM];
78     int             j, m, *iptr, idum;
79     gmx_int64_t     sdum;
80     real           *ptr;
81     unsigned short  us;
82     double          d = 0;
83     float           f = 0;
84
85     gmx_fio_check_nitem(eio, nitem, srcfile, line);
86     switch (eio)
87     {
88         case eioREAL:
89             if (fio->bDouble)
90             {
91                 if (item && !fio->bRead)
92                 {
93                     d = *((real *) item);
94                 }
95                 res = xdr_double(fio->xdr, &d);
96                 if (item)
97                 {
98                     *((real *) item) = d;
99                 }
100             }
101             else
102             {
103                 if (item && !fio->bRead)
104                 {
105                     f = *((real *) item);
106                 }
107                 res = xdr_float(fio->xdr, &f);
108                 if (item)
109                 {
110                     *((real *) item) = f;
111                 }
112             }
113             break;
114         case eioFLOAT:
115             if (item && !fio->bRead)
116             {
117                 f = *((float *) item);
118             }
119             res = xdr_float(fio->xdr, &f);
120             if (item)
121             {
122                 *((float *) item) = f;
123             }
124             break;
125         case eioDOUBLE:
126             if (item && !fio->bRead)
127             {
128                 d = *((double *) item);
129             }
130             res = xdr_double(fio->xdr, &d);
131             if (item)
132             {
133                 *((double *) item) = d;
134             }
135             break;
136         case eioINT:
137             if (item && !fio->bRead)
138             {
139                 idum = *(int *) item;
140             }
141             res = xdr_int(fio->xdr, &idum);
142             if (item)
143             {
144                 *(int *) item = idum;
145             }
146             break;
147         case eioINT64:
148             if (item && !fio->bRead)
149             {
150                 sdum = *(gmx_int64_t *) item;
151             }
152             res = xdr_int64(fio->xdr, &sdum);
153             if (item)
154             {
155                 *(gmx_int64_t *) item = sdum;
156             }
157             break;
158         case eioUCHAR:
159             if (item && !fio->bRead)
160             {
161                 ucdum = *(unsigned char *) item;
162             }
163             res = xdr_u_char(fio->xdr, &ucdum);
164             if (item)
165             {
166                 *(unsigned char *) item = ucdum;
167             }
168             break;
169         case eioNUCHAR:
170             ucptr = (unsigned char *) item;
171             res   = 1;
172             for (j = 0; (j < nitem) && res; j++)
173             {
174                 res = xdr_u_char(fio->xdr, &(ucptr[j]));
175             }
176             break;
177         case eioUSHORT:
178             if (item && !fio->bRead)
179             {
180                 us = *(unsigned short *) item;
181             }
182             res = xdr_u_short(fio->xdr, (unsigned short *) &us);
183             if (item)
184             {
185                 *(unsigned short *) item = us;
186             }
187             break;
188         case eioRVEC:
189             if (fio->bDouble)
190             {
191                 if (item && !fio->bRead)
192                 {
193                     for (m = 0; (m < DIM); m++)
194                     {
195                         dvec[m] = ((real *) item)[m];
196                     }
197                 }
198                 res = xdr_vector(fio->xdr, (char *) dvec, DIM,
199                                  (unsigned int) sizeof(double),
200                                  (xdrproc_t) xdr_double);
201                 if (item)
202                 {
203                     for (m = 0; (m < DIM); m++)
204                     {
205                         ((real *) item)[m] = dvec[m];
206                     }
207                 }
208             }
209             else
210             {
211                 if (item && !fio->bRead)
212                 {
213                     for (m = 0; (m < DIM); m++)
214                     {
215                         fvec[m] = ((real *) item)[m];
216                     }
217                 }
218                 res = xdr_vector(fio->xdr, (char *) fvec, DIM,
219                                  (unsigned int) sizeof(float),
220                                  (xdrproc_t) xdr_float);
221                 if (item)
222                 {
223                     for (m = 0; (m < DIM); m++)
224                     {
225                         ((real *) item)[m] = fvec[m];
226                     }
227                 }
228             }
229             break;
230         case eioNRVEC:
231             ptr = NULL;
232             res = 1;
233             for (j = 0; (j < nitem) && res; j++)
234             {
235                 if (item)
236                 {
237                     ptr = ((rvec *) item)[j];
238                 }
239                 res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
240             }
241             break;
242         case eioIVEC:
243             iptr = (int *) item;
244             res  = 1;
245             for (m = 0; (m < DIM) && res; m++)
246             {
247                 if (item && !fio->bRead)
248                 {
249                     idum = iptr[m];
250                 }
251                 res = xdr_int(fio->xdr, &idum);
252                 if (item)
253                 {
254                     iptr[m] = idum;
255                 }
256             }
257             break;
258         case eioSTRING:
259         {
260             char *cptr;
261             int   slen;
262
263             if (item)
264             {
265                 if (!fio->bRead)
266                 {
267                     slen = strlen((char *) item) + 1;
268                 }
269                 else
270                 {
271                     slen = 0;
272                 }
273             }
274             else
275             {
276                 slen = 0;
277             }
278
279             if (xdr_int(fio->xdr, &slen) <= 0)
280             {
281                 gmx_fatal(FARGS, "wrong string length %d for string %s"
282                           " (source %s, line %d)", slen, desc, srcfile, line);
283             }
284             if (!item && fio->bRead)
285             {
286                 snew(cptr, slen);
287             }
288             else
289             {
290                 cptr = (char *)item;
291             }
292             if (cptr)
293             {
294                 res = xdr_string(fio->xdr, &cptr, slen);
295             }
296             else
297             {
298                 res = 1;
299             }
300             if (!item && fio->bRead)
301             {
302                 sfree(cptr);
303             }
304             break;
305         }
306         default:
307             gmx_fio_fe(fio, eio, desc, srcfile, line);
308     }
309     if ((res == 0) && (fio->bDebug))
310     {
311         fprintf(stderr, "Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
312                 eioNames[eio], desc, fio->fn, srcfile, line);
313     }
314
315     return (res != 0);
316 }
317
318
319 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
320                            const char *desc, const char *srcfile, int line)
321 {
322     return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
323 }
324
325
326 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
327                             const char *desc, const char *srcfile, int line)
328 {
329     void *it = (void*)item; /* ugh.. */
330     return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
331 }
332
333 #endif