Merge branch 'release-4-6'
[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, 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 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include <ctype.h>
42 #include <stdio.h>
43 #include <errno.h>
44 #ifdef HAVE_IO_H
45 #include <io.h>
46 #endif
47
48 #include "gmx_fatal.h"
49 #include "macros.h"
50 #include "smalloc.h"
51 #include "futil.h"
52 #include "filenm.h"
53 #include "string2.h"
54 #include "gmxfio.h"
55 #include "md5.h"
56
57 #include "gmxfio_int.h"
58
59 /* This is the part that reads xdr files.  */
60
61
62 /* file type functions */
63 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
64                            const char *desc, const char *srcfile, int line);
65 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
66                             const char *desc, const char *srcfile, int line);
67
68
69 const t_iotype xdr_iotype = {do_xdrread, do_xdrwrite};
70
71
72 #ifdef USE_XDR
73
74 static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
75                        const char *desc, const char *srcfile, int line)
76 {
77     unsigned char   ucdum, *ucptr;
78     bool_t          res = 0;
79     float           fvec[DIM];
80     double          dvec[DIM];
81     int             j, m, *iptr, idum;
82     gmx_int64_t     sdum;
83     real           *ptr;
84     unsigned short  us;
85     double          d = 0;
86     float           f = 0;
87
88     gmx_fio_check_nitem(eio, nitem, srcfile, line);
89     switch (eio)
90     {
91         case eioREAL:
92             if (fio->bDouble)
93             {
94                 if (item && !fio->bRead)
95                 {
96                     d = *((real *) item);
97                 }
98                 res = xdr_double(fio->xdr, &d);
99                 if (item)
100                 {
101                     *((real *) item) = d;
102                 }
103             }
104             else
105             {
106                 if (item && !fio->bRead)
107                 {
108                     f = *((real *) item);
109                 }
110                 res = xdr_float(fio->xdr, &f);
111                 if (item)
112                 {
113                     *((real *) item) = f;
114                 }
115             }
116             break;
117         case eioFLOAT:
118             if (item && !fio->bRead)
119             {
120                 f = *((float *) item);
121             }
122             res = xdr_float(fio->xdr, &f);
123             if (item)
124             {
125                 *((float *) item) = f;
126             }
127             break;
128         case eioDOUBLE:
129             if (item && !fio->bRead)
130             {
131                 d = *((double *) item);
132             }
133             res = xdr_double(fio->xdr, &d);
134             if (item)
135             {
136                 *((double *) item) = d;
137             }
138             break;
139         case eioINT:
140             if (item && !fio->bRead)
141             {
142                 idum = *(int *) item;
143             }
144             res = xdr_int(fio->xdr, &idum);
145             if (item)
146             {
147                 *(int *) item = idum;
148             }
149             break;
150         case eioINT64:
151             if (item && !fio->bRead)
152             {
153                 sdum = *(gmx_int64_t *) item;
154             }
155             res = xdr_int64(fio->xdr, &sdum);
156             if (item)
157             {
158                 *(gmx_int64_t *) item = sdum;
159             }
160             break;
161         case eioUCHAR:
162             if (item && !fio->bRead)
163             {
164                 ucdum = *(unsigned char *) item;
165             }
166             res = xdr_u_char(fio->xdr, &ucdum);
167             if (item)
168             {
169                 *(unsigned char *) item = ucdum;
170             }
171             break;
172         case eioNUCHAR:
173             ucptr = (unsigned char *) item;
174             res   = 1;
175             for (j = 0; (j < nitem) && res; j++)
176             {
177                 res = xdr_u_char(fio->xdr, &(ucptr[j]));
178             }
179             break;
180         case eioUSHORT:
181             if (item && !fio->bRead)
182             {
183                 us = *(unsigned short *) item;
184             }
185             res = xdr_u_short(fio->xdr, (unsigned short *) &us);
186             if (item)
187             {
188                 *(unsigned short *) item = us;
189             }
190             break;
191         case eioRVEC:
192             if (fio->bDouble)
193             {
194                 if (item && !fio->bRead)
195                 {
196                     for (m = 0; (m < DIM); m++)
197                     {
198                         dvec[m] = ((real *) item)[m];
199                     }
200                 }
201                 res = xdr_vector(fio->xdr, (char *) dvec, DIM,
202                                  (unsigned int) sizeof(double),
203                                  (xdrproc_t) xdr_double);
204                 if (item)
205                 {
206                     for (m = 0; (m < DIM); m++)
207                     {
208                         ((real *) item)[m] = dvec[m];
209                     }
210                 }
211             }
212             else
213             {
214                 if (item && !fio->bRead)
215                 {
216                     for (m = 0; (m < DIM); m++)
217                     {
218                         fvec[m] = ((real *) item)[m];
219                     }
220                 }
221                 res = xdr_vector(fio->xdr, (char *) fvec, DIM,
222                                  (unsigned int) sizeof(float),
223                                  (xdrproc_t) xdr_float);
224                 if (item)
225                 {
226                     for (m = 0; (m < DIM); m++)
227                     {
228                         ((real *) item)[m] = fvec[m];
229                     }
230                 }
231             }
232             break;
233         case eioNRVEC:
234             ptr = NULL;
235             res = 1;
236             for (j = 0; (j < nitem) && res; j++)
237             {
238                 if (item)
239                 {
240                     ptr = ((rvec *) item)[j];
241                 }
242                 res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
243             }
244             break;
245         case eioIVEC:
246             iptr = (int *) item;
247             res  = 1;
248             for (m = 0; (m < DIM) && res; m++)
249             {
250                 if (item && !fio->bRead)
251                 {
252                     idum = iptr[m];
253                 }
254                 res = xdr_int(fio->xdr, &idum);
255                 if (item)
256                 {
257                     iptr[m] = idum;
258                 }
259             }
260             break;
261         case eioSTRING:
262         {
263             char *cptr;
264             int   slen;
265
266             if (item)
267             {
268                 if (!fio->bRead)
269                 {
270                     slen = strlen((char *) item) + 1;
271                 }
272                 else
273                 {
274                     slen = 0;
275                 }
276             }
277             else
278             {
279                 slen = 0;
280             }
281
282             if (xdr_int(fio->xdr, &slen) <= 0)
283             {
284                 gmx_fatal(FARGS, "wrong string length %d for string %s"
285                           " (source %s, line %d)", slen, desc, srcfile, line);
286             }
287             if (!item && fio->bRead)
288             {
289                 snew(cptr, slen);
290             }
291             else
292             {
293                 cptr = (char *)item;
294             }
295             if (cptr)
296             {
297                 res = xdr_string(fio->xdr, &cptr, slen);
298             }
299             else
300             {
301                 res = 1;
302             }
303             if (!item && fio->bRead)
304             {
305                 sfree(cptr);
306             }
307             break;
308         }
309         default:
310             gmx_fio_fe(fio, eio, desc, srcfile, line);
311     }
312     if ((res == 0) && (fio->bDebug))
313     {
314         fprintf(stderr, "Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
315                 eioNames[eio], desc, fio->fn, srcfile, line);
316     }
317
318     return (res != 0);
319 }
320
321
322 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
323                            const char *desc, const char *srcfile, int line)
324 {
325     return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
326 }
327
328
329 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
330                             const char *desc, const char *srcfile, int line)
331 {
332     void *it = (void*)item; /* ugh.. */
333     return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
334 }
335
336 #endif