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