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_large_int_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 eioGMX_LARGE_INT:
151             /* do_xdr will not generate a warning when a 64bit gmx_large_int_t
152              * value that is out of 32bit range is read into a 32bit gmx_large_int_t.
153              */
154             if (item && !fio->bRead)
155             {
156                 sdum = *(gmx_large_int_t *) item;
157             }
158             res = xdr_gmx_large_int(fio->xdr, &sdum);
159             if (item)
160             {
161                 *(gmx_large_int_t *) item = sdum;
162             }
163             break;
164         case eioUCHAR:
165             if (item && !fio->bRead)
166             {
167                 ucdum = *(unsigned char *) item;
168             }
169             res = xdr_u_char(fio->xdr, &ucdum);
170             if (item)
171             {
172                 *(unsigned char *) item = ucdum;
173             }
174             break;
175         case eioNUCHAR:
176             ucptr = (unsigned char *) item;
177             res   = 1;
178             for (j = 0; (j < nitem) && res; j++)
179             {
180                 res = xdr_u_char(fio->xdr, &(ucptr[j]));
181             }
182             break;
183         case eioUSHORT:
184             if (item && !fio->bRead)
185             {
186                 us = *(unsigned short *) item;
187             }
188             res = xdr_u_short(fio->xdr, (unsigned short *) &us);
189             if (item)
190             {
191                 *(unsigned short *) item = us;
192             }
193             break;
194         case eioRVEC:
195             if (fio->bDouble)
196             {
197                 if (item && !fio->bRead)
198                 {
199                     for (m = 0; (m < DIM); m++)
200                     {
201                         dvec[m] = ((real *) item)[m];
202                     }
203                 }
204                 res = xdr_vector(fio->xdr, (char *) dvec, DIM,
205                                  (unsigned int) sizeof(double),
206                                  (xdrproc_t) xdr_double);
207                 if (item)
208                 {
209                     for (m = 0; (m < DIM); m++)
210                     {
211                         ((real *) item)[m] = dvec[m];
212                     }
213                 }
214             }
215             else
216             {
217                 if (item && !fio->bRead)
218                 {
219                     for (m = 0; (m < DIM); m++)
220                     {
221                         fvec[m] = ((real *) item)[m];
222                     }
223                 }
224                 res = xdr_vector(fio->xdr, (char *) fvec, DIM,
225                                  (unsigned int) sizeof(float),
226                                  (xdrproc_t) xdr_float);
227                 if (item)
228                 {
229                     for (m = 0; (m < DIM); m++)
230                     {
231                         ((real *) item)[m] = fvec[m];
232                     }
233                 }
234             }
235             break;
236         case eioNRVEC:
237             ptr = NULL;
238             res = 1;
239             for (j = 0; (j < nitem) && res; j++)
240             {
241                 if (item)
242                 {
243                     ptr = ((rvec *) item)[j];
244                 }
245                 res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
246             }
247             break;
248         case eioIVEC:
249             iptr = (int *) item;
250             res  = 1;
251             for (m = 0; (m < DIM) && res; m++)
252             {
253                 if (item && !fio->bRead)
254                 {
255                     idum = iptr[m];
256                 }
257                 res = xdr_int(fio->xdr, &idum);
258                 if (item)
259                 {
260                     iptr[m] = idum;
261                 }
262             }
263             break;
264         case eioSTRING:
265         {
266             char *cptr;
267             int   slen;
268
269             if (item)
270             {
271                 if (!fio->bRead)
272                 {
273                     slen = strlen((char *) item) + 1;
274                 }
275                 else
276                 {
277                     slen = 0;
278                 }
279             }
280             else
281             {
282                 slen = 0;
283             }
284
285             if (xdr_int(fio->xdr, &slen) <= 0)
286             {
287                 gmx_fatal(FARGS, "wrong string length %d for string %s"
288                           " (source %s, line %d)", slen, desc, srcfile, line);
289             }
290             if (!item && fio->bRead)
291             {
292                 snew(cptr, slen);
293             }
294             else
295             {
296                 cptr = (char *)item;
297             }
298             if (cptr)
299             {
300                 res = xdr_string(fio->xdr, &cptr, slen);
301             }
302             else
303             {
304                 res = 1;
305             }
306             if (!item && fio->bRead)
307             {
308                 sfree(cptr);
309             }
310             break;
311         }
312         default:
313             gmx_fio_fe(fio, eio, desc, srcfile, line);
314     }
315     if ((res == 0) && (fio->bDebug))
316     {
317         fprintf(stderr, "Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
318                 eioNames[eio], desc, fio->fn, srcfile, line);
319     }
320
321     return (res != 0);
322 }
323
324
325 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio,
326                            const char *desc, const char *srcfile, int line)
327 {
328     return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
329 }
330
331
332 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio,
333                             const char *desc, const char *srcfile, int line)
334 {
335     void *it = (void*)item; /* ugh.. */
336     return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
337 }
338
339 #endif