05893fdd48cb75539cedb0927d70031167c3de81
[alexxy/gromacs.git] / src / gmxlib / gmxfio_xdr.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  * 
4  *                This source code is part of
5  * 
6  *                 G   R   O   M   A   C   S
7  * 
8  *          GROningen MAchine for Chemical Simulations
9  * 
10  *                        VERSION 3.2.0
11  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13  * Copyright (c) 2001-2004, The GROMACS development team,
14  * check out http://www.gromacs.org for more information.
15
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  * 
21  * If you want to redistribute modifications, please consider that
22  * scientific software is very special. Version control is crucial -
23  * bugs must be traceable. We will be happy to consider code for
24  * inclusion in the official distribution, but derived work must not
25  * be called official GROMACS. Details are found in the README & COPYING
26  * files - if they are missing, get the official version at www.gromacs.org.
27  * 
28  * To help us fund GROMACS development, we humbly ask that you cite
29  * the papers on the package - you can find them in the top README file.
30  * 
31  * For more info, check our website at http://www.gromacs.org
32  * 
33  * And Hey:
34  * GROningen Mixture of Alchemy and Childrens' Stories
35  */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <ctype.h>
41 #include <stdio.h>
42 #include <errno.h>
43 #ifdef HAVE_IO_H
44 #include <io.h>
45 #endif
46
47 #include "gmx_fatal.h"
48 #include "macros.h"
49 #include "smalloc.h"
50 #include "futil.h"
51 #include "filenm.h"
52 #include "string2.h"
53 #include "gmxfio.h"
54 #include "md5.h"
55
56 #ifdef GMX_THREADS
57 #include "thread_mpi.h"
58 #endif
59
60 #include "gmxfio_int.h"
61
62 /* This is the part that reads xdr files.  */
63
64
65 /* file type functions */
66 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio, 
67                        const char *desc, const char *srcfile, int line);
68 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio, 
69                         const char *desc, const char *srcfile, int line);
70
71
72 const t_iotype xdr_iotype={do_xdrread, do_xdrwrite};
73
74
75 #ifdef USE_XDR
76
77 static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, 
78                    const char *desc, const char *srcfile, int line)
79 {
80     unsigned char ucdum, *ucptr;
81     bool_t res = 0;
82     float fvec[DIM];
83     double dvec[DIM];
84     int j, m, *iptr, idum;
85     gmx_large_int_t sdum;
86     real *ptr;
87     unsigned short us;
88     double d = 0;
89     float f = 0;
90
91     gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
92     switch (eio)
93     {
94     case eioREAL:
95         if (fio->bDouble)
96         {
97             if (item && !fio->bRead)
98                 d = *((real *) item);
99             res = xdr_double(fio->xdr, &d);
100             if (item)
101                 *((real *) item) = d;
102         }
103         else
104         {
105             if (item && !fio->bRead)
106                 f = *((real *) item);
107             res = xdr_float(fio->xdr, &f);
108             if (item)
109                 *((real *) item) = f;
110         }
111         break;
112     case eioFLOAT:
113         if (item && !fio->bRead)
114             f = *((float *) item);
115         res = xdr_float(fio->xdr, &f);
116         if (item)
117             *((float *) item) = f;
118         break;
119     case eioDOUBLE:
120         if (item && !fio->bRead)
121             d = *((double *) item);
122         res = xdr_double(fio->xdr, &d);
123         if (item)
124             *((double *) item) = d;
125         break;
126     case eioINT:
127         if (item && !fio->bRead)
128             idum = *(int *) item;
129         res = xdr_int(fio->xdr, &idum);
130         if (item)
131             *(int *) item = idum;
132         break;
133     case eioGMX_LARGE_INT:
134         /* do_xdr will not generate a warning when a 64bit gmx_large_int_t
135          * value that is out of 32bit range is read into a 32bit gmx_large_int_t.
136          */
137         if (item && !fio->bRead)
138             sdum = *(gmx_large_int_t *) item;
139         res = xdr_gmx_large_int(fio->xdr, &sdum, NULL);
140         if (item)
141             *(gmx_large_int_t *) item = sdum;
142         break;
143     case eioUCHAR:
144         if (item && !fio->bRead)
145             ucdum = *(unsigned char *) item;
146         res = xdr_u_char(fio->xdr, &ucdum);
147         if (item)
148             *(unsigned char *) item = ucdum;
149         break;
150     case eioNUCHAR:
151         ucptr = (unsigned char *) item;
152         res = 1;
153         for (j = 0; (j < nitem) && res; j++)
154         {
155             res = xdr_u_char(fio->xdr, &(ucptr[j]));
156         }
157         break;
158     case eioUSHORT:
159         if (item && !fio->bRead)
160             us = *(unsigned short *) item;
161         res = xdr_u_short(fio->xdr, (unsigned short *) &us);
162         if (item)
163             *(unsigned short *) item = us;
164         break;
165     case eioRVEC:
166         if (fio->bDouble)
167         {
168             if (item && !fio->bRead)
169                 for (m = 0; (m < DIM); m++)
170                     dvec[m] = ((real *) item)[m];
171             res = xdr_vector(fio->xdr, (char *) dvec, DIM,
172                              (unsigned int) sizeof(double),
173                              (xdrproc_t) xdr_double);
174             if (item)
175                 for (m = 0; (m < DIM); m++)
176                     ((real *) item)[m] = dvec[m];
177         }
178         else
179         {
180             if (item && !fio->bRead)
181                 for (m = 0; (m < DIM); m++)
182                     fvec[m] = ((real *) item)[m];
183             res = xdr_vector(fio->xdr, (char *) fvec, DIM,
184                              (unsigned int) sizeof(float),
185                              (xdrproc_t) xdr_float);
186             if (item)
187                 for (m = 0; (m < DIM); m++)
188                     ((real *) item)[m] = fvec[m];
189         }
190         break;
191     case eioNRVEC:
192         ptr = NULL;
193         res = 1;
194         for (j = 0; (j < nitem) && res; j++)
195         {
196             if (item)
197                 ptr = ((rvec *) item)[j];
198             res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
199         }
200         break;
201     case eioIVEC:
202         iptr = (int *) item;
203         res = 1;
204         for (m = 0; (m < DIM) && res; m++)
205         {
206             if (item && !fio->bRead)
207                 idum = iptr[m];
208             res = xdr_int(fio->xdr, &idum);
209             if (item)
210                 iptr[m] = idum;
211         }
212         break;
213     case eioSTRING:
214     {
215         char *cptr;
216         int slen;
217
218         if (item)
219         {
220             if (!fio->bRead)
221                 slen = strlen((char *) item) + 1;
222             else
223                 slen = 0;
224         }
225         else
226             slen = 0;
227
228         if (xdr_int(fio->xdr, &slen) <= 0)
229             gmx_fatal(FARGS, "wrong string length %d for string %s"
230                       " (source %s, line %d)",slen,desc,srcfile,line);
231         if (!item && fio->bRead)
232             snew(cptr,slen);
233         else
234             cptr=(char *)item;
235         if (cptr)
236             res = xdr_string(fio->xdr,&cptr,slen);
237         else
238             res = 1;
239         if (!item && fio->bRead)
240             sfree(cptr);
241         break;
242     }
243     default:
244         gmx_fio_fe(fio, eio, desc, srcfile, line);
245     }
246     if ((res == 0) && (fio->bDebug))
247         fprintf(stderr,"Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
248                 eioNames[eio],desc,fio->fn,srcfile,line);
249
250     return (res != 0);
251 }
252
253
254 static gmx_bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio, 
255                        const char *desc, const char *srcfile, int line)
256 {
257     return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
258 }
259
260
261 static gmx_bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio, 
262                         const char *desc, const char *srcfile, int line)
263 {
264     void *it=(void*)item; /* ugh.. */
265     return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
266 }
267
268 #endif
269
270