Reorder code within gmxfio
[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 static const char *eioNames[eioNR] =
50 {
51     "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
52     "IVEC", "STRING"
53 };
54
55 /* check the number of items given against the type */
56 static void gmx_fio_check_nitem(int eio, int nitem, const char *file, int line)
57 {
58     if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR)))
59     {
60         gmx_fatal(FARGS,
61                   "nitem (%d) may differ from 1 only for %s or %s, not   for %s"
62                   "(%s, %d)", nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC],
63                   eioNames[eio], file, line);
64     }
65 }
66
67
68 /* output a data type error. */
69 static void gmx_fio_fe(t_fileio *fio, int eio, const char *desc,
70                        const char *srcfile, int line)
71 {
72
73     gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d",
74               fio->bRead ? "read" : "write", desc, eio,
75               ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
76               srcfile, line);
77 }
78
79 /* This is the part that reads xdr files.  */
80
81 static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
82                        const char *desc, const char *srcfile, int line)
83 {
84     unsigned char   ucdum, *ucptr;
85     bool_t          res = 0;
86     float           fvec[DIM];
87     double          dvec[DIM];
88     int             j, m, *iptr, idum;
89     gmx_int64_t     sdum;
90     real           *ptr;
91     unsigned short  us;
92     double          d = 0;
93     float           f = 0;
94
95     gmx_fio_check_nitem(eio, nitem, srcfile, line);
96     switch (eio)
97     {
98         case eioREAL:
99             if (fio->bDouble)
100             {
101                 if (item && !fio->bRead)
102                 {
103                     d = *((real *) item);
104                 }
105                 res = xdr_double(fio->xdr, &d);
106                 if (item)
107                 {
108                     *((real *) item) = d;
109                 }
110             }
111             else
112             {
113                 if (item && !fio->bRead)
114                 {
115                     f = *((real *) item);
116                 }
117                 res = xdr_float(fio->xdr, &f);
118                 if (item)
119                 {
120                     *((real *) item) = f;
121                 }
122             }
123             break;
124         case eioFLOAT:
125             if (item && !fio->bRead)
126             {
127                 f = *((float *) item);
128             }
129             res = xdr_float(fio->xdr, &f);
130             if (item)
131             {
132                 *((float *) item) = f;
133             }
134             break;
135         case eioDOUBLE:
136             if (item && !fio->bRead)
137             {
138                 d = *((double *) item);
139             }
140             res = xdr_double(fio->xdr, &d);
141             if (item)
142             {
143                 *((double *) item) = d;
144             }
145             break;
146         case eioINT:
147             if (item && !fio->bRead)
148             {
149                 idum = *(int *) item;
150             }
151             res = xdr_int(fio->xdr, &idum);
152             if (item)
153             {
154                 *(int *) item = idum;
155             }
156             break;
157         case eioINT64:
158             if (item && !fio->bRead)
159             {
160                 sdum = *(gmx_int64_t *) item;
161             }
162             res = xdr_int64(fio->xdr, &sdum);
163             if (item)
164             {
165                 *(gmx_int64_t *) item = sdum;
166             }
167             break;
168         case eioUCHAR:
169             if (item && !fio->bRead)
170             {
171                 ucdum = *(unsigned char *) item;
172             }
173             res = xdr_u_char(fio->xdr, &ucdum);
174             if (item)
175             {
176                 *(unsigned char *) item = ucdum;
177             }
178             break;
179         case eioNUCHAR:
180             ucptr = (unsigned char *) item;
181             res   = 1;
182             for (j = 0; (j < nitem) && res; j++)
183             {
184                 res = xdr_u_char(fio->xdr, &(ucptr[j]));
185             }
186             break;
187         case eioUSHORT:
188             if (item && !fio->bRead)
189             {
190                 us = *(unsigned short *) item;
191             }
192             res = xdr_u_short(fio->xdr, (unsigned short *) &us);
193             if (item)
194             {
195                 *(unsigned short *) item = us;
196             }
197             break;
198         case eioRVEC:
199             if (fio->bDouble)
200             {
201                 if (item && !fio->bRead)
202                 {
203                     for (m = 0; (m < DIM); m++)
204                     {
205                         dvec[m] = ((real *) item)[m];
206                     }
207                 }
208                 res = xdr_vector(fio->xdr, (char *) dvec, DIM,
209                                  (unsigned int) sizeof(double),
210                                  (xdrproc_t) xdr_double);
211                 if (item)
212                 {
213                     for (m = 0; (m < DIM); m++)
214                     {
215                         ((real *) item)[m] = dvec[m];
216                     }
217                 }
218             }
219             else
220             {
221                 if (item && !fio->bRead)
222                 {
223                     for (m = 0; (m < DIM); m++)
224                     {
225                         fvec[m] = ((real *) item)[m];
226                     }
227                 }
228                 res = xdr_vector(fio->xdr, (char *) fvec, DIM,
229                                  (unsigned int) sizeof(float),
230                                  (xdrproc_t) xdr_float);
231                 if (item)
232                 {
233                     for (m = 0; (m < DIM); m++)
234                     {
235                         ((real *) item)[m] = fvec[m];
236                     }
237                 }
238             }
239             break;
240         case eioNRVEC:
241             ptr = NULL;
242             res = 1;
243             for (j = 0; (j < nitem) && res; j++)
244             {
245                 if (item)
246                 {
247                     ptr = ((rvec *) item)[j];
248                 }
249                 res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
250             }
251             break;
252         case eioIVEC:
253             iptr = (int *) item;
254             res  = 1;
255             for (m = 0; (m < DIM) && res; m++)
256             {
257                 if (item && !fio->bRead)
258                 {
259                     idum = iptr[m];
260                 }
261                 res = xdr_int(fio->xdr, &idum);
262                 if (item)
263                 {
264                     iptr[m] = idum;
265                 }
266             }
267             break;
268         case eioSTRING:
269         {
270             char *cptr;
271             int   slen;
272
273             if (item)
274             {
275                 if (!fio->bRead)
276                 {
277                     slen = strlen((char *) item) + 1;
278                 }
279                 else
280                 {
281                     slen = 0;
282                 }
283             }
284             else
285             {
286                 slen = 0;
287             }
288
289             if (xdr_int(fio->xdr, &slen) <= 0)
290             {
291                 gmx_fatal(FARGS, "wrong string length %d for string %s"
292                           " (source %s, line %d)", slen, desc, srcfile, line);
293             }
294             if (!item && fio->bRead)
295             {
296                 snew(cptr, slen);
297             }
298             else
299             {
300                 cptr = (char *)item;
301             }
302             if (cptr)
303             {
304                 res = xdr_string(fio->xdr, &cptr, slen);
305             }
306             else
307             {
308                 res = 1;
309             }
310             if (!item && fio->bRead)
311             {
312                 sfree(cptr);
313             }
314             break;
315         }
316         default:
317             gmx_fio_fe(fio, eio, desc, srcfile, line);
318     }
319     if ((res == 0) && (fio->bDebug))
320     {
321         fprintf(stderr, "Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
322                 eioNames[eio], desc, fio->fn, srcfile, line);
323     }
324
325     return (res != 0);
326 }
327
328 /*******************************************************************
329  *
330  * READ/WRITE FUNCTIONS
331  *
332  *******************************************************************/
333
334 gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item,
335                                const char *desc, const char *srcfile, int line)
336 {
337     gmx_bool ret;
338     void    *it = (void*)item; /* ugh.. */
339     gmx_fio_lock(fio);
340     ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line);
341     gmx_fio_unlock(fio);
342     return ret;
343 }
344
345 gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item,
346                           const char *desc, const char *srcfile, int line)
347 {
348     gmx_bool ret;
349     gmx_fio_lock(fio);
350     ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line);
351     gmx_fio_unlock(fio);
352     return ret;
353
354 }
355
356 gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item,
357                            const char *desc, const char *srcfile, int line)
358 {
359     gmx_bool ret;
360     gmx_fio_lock(fio);
361     ret = do_xdr(fio, item, 1, eioFLOAT, desc, srcfile, line);
362     gmx_fio_unlock(fio);
363     return ret;
364 }
365
366 gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item,
367                             const char *desc, const char *srcfile, int line)
368 {
369     gmx_bool ret;
370     gmx_fio_lock(fio);
371     ret = do_xdr(fio, item, 1, eioDOUBLE, desc, srcfile, line);
372     gmx_fio_unlock(fio);
373     return ret;
374 }
375
376
377 gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item,
378                               const char *desc, const char *srcfile, int line)
379 {
380     gmx_bool ret;
381
382     gmx_fio_lock(fio);
383     if (fio->bRead)
384     {
385         int itmp = 0;
386         ret      = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
387         *item    = itmp;
388     }
389     else
390     {
391         int itmp = *item;
392         ret      = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
393     }
394     gmx_fio_unlock(fio);
395     return ret;
396 }
397
398 gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item,
399                          const char *desc, const char *srcfile, int line)
400 {
401     gmx_bool ret;
402     gmx_fio_lock(fio);
403     ret = do_xdr(fio, item, 1, eioINT, desc, srcfile, line);
404     gmx_fio_unlock(fio);
405     return ret;
406 }
407
408 gmx_bool gmx_fio_doe_int64(t_fileio *fio, gmx_int64_t *item,
409                            const char *desc, const char *srcfile, int line)
410 {
411     gmx_bool ret;
412     gmx_fio_lock(fio);
413     ret = do_xdr(fio, item, 1, eioINT64, desc, srcfile, line);
414     gmx_fio_unlock(fio);
415     return ret;
416 }
417
418 gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
419                            const char *desc, const char *srcfile, int line)
420 {
421     gmx_bool ret;
422     gmx_fio_lock(fio);
423     ret = do_xdr(fio, item, 1, eioUCHAR, desc, srcfile, line);
424     gmx_fio_unlock(fio);
425     return ret;
426 }
427
428 gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
429                             const char *desc, const char *srcfile, int line)
430 {
431     gmx_bool ret;
432     gmx_fio_lock(fio);
433     ret = do_xdr(fio, item, 1, eioUSHORT, desc, srcfile, line);
434     gmx_fio_unlock(fio);
435     return ret;
436 }
437
438 gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
439                           const char *desc, const char *srcfile, int line)
440 {
441     gmx_bool ret;
442     gmx_fio_lock(fio);
443     ret = do_xdr(fio, item, 1, eioRVEC, desc, srcfile, line);
444     gmx_fio_unlock(fio);
445     return ret;
446 }
447
448 gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
449                           const char *desc, const char *srcfile, int line)
450 {
451     gmx_bool ret;
452     gmx_fio_lock(fio);
453     ret = do_xdr(fio, item, 1, eioIVEC, desc, srcfile, line);
454     gmx_fio_unlock(fio);
455     return ret;
456 }
457
458 gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item,
459                             const char *desc, const char *srcfile, int line)
460 {
461     gmx_bool ret;
462     gmx_fio_lock(fio);
463     ret = do_xdr(fio, item, 1, eioSTRING, desc, srcfile, line);
464     gmx_fio_unlock(fio);
465     return ret;
466 }
467
468
469 /* Array reading & writing */
470
471 gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
472                            const char *desc, const char *srcfile, int line)
473 {
474     gmx_bool ret = TRUE;
475     int      i;
476     gmx_fio_lock(fio);
477     for (i = 0; i < n; i++)
478     {
479         ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc,
480                             srcfile, line);
481     }
482     gmx_fio_unlock(fio);
483     return ret;
484 }
485
486
487
488 gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n,
489                             const char *desc, const char *srcfile, int line)
490 {
491     gmx_bool ret = TRUE;
492     int      i;
493     gmx_fio_lock(fio);
494     for (i = 0; i < n; i++)
495     {
496         ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc,
497                             srcfile, line);
498     }
499     gmx_fio_unlock(fio);
500     return ret;
501 }
502
503
504
505 gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
506                              const char *desc, const char *srcfile, int line)
507 {
508     gmx_bool ret = TRUE;
509     int      i;
510     gmx_fio_lock(fio);
511     for (i = 0; i < n; i++)
512     {
513         ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc,
514                             srcfile, line);
515     }
516     gmx_fio_unlock(fio);
517     return ret;
518 }
519
520
521
522 gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n,
523                                const char *desc, const char *srcfile, int line)
524 {
525     gmx_bool ret = TRUE;
526     int      i;
527
528     gmx_fio_lock(fio);
529     for (i = 0; i < n; i++)
530     {
531         if (fio->bRead)
532         {
533             int itmp = 0;
534             ret      = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
535             item[i]  = itmp;
536         }
537         else
538         {
539             int itmp = item[i];
540             ret      = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
541         }
542     }
543     gmx_fio_unlock(fio);
544     return ret;
545 }
546
547 gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
548                           const char *desc, const char *srcfile, int line)
549 {
550     gmx_bool ret = TRUE;
551     int      i;
552     gmx_fio_lock(fio);
553     for (i = 0; i < n; i++)
554     {
555         ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc,
556                             srcfile, line);
557     }
558     gmx_fio_unlock(fio);
559     return ret;
560 }
561
562
563
564 gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, gmx_int64_t *item, int n,
565                             const char *desc, const char *srcfile, int line)
566 {
567     gmx_bool ret = TRUE;
568     int      i;
569     gmx_fio_lock(fio);
570     for (i = 0; i < n; i++)
571     {
572         ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc,
573                             srcfile, line);
574     }
575     gmx_fio_unlock(fio);
576     return ret;
577 }
578
579
580
581 gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
582                             const char *desc, const char *srcfile, int line)
583 {
584     gmx_bool ret = TRUE;
585     gmx_fio_lock(fio);
586     ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc,
587                         srcfile, line);
588     gmx_fio_unlock(fio);
589     return ret;
590 }
591
592
593
594 gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
595                              const char *desc, const char *srcfile, int line)
596 {
597     gmx_bool ret = TRUE;
598     int      i;
599     gmx_fio_lock(fio);
600     for (i = 0; i < n; i++)
601     {
602         ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc,
603                             srcfile, line);
604     }
605     gmx_fio_unlock(fio);
606     return ret;
607 }
608
609
610
611 gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
612                            const char *desc, const char *srcfile, int line)
613 {
614     gmx_bool ret = TRUE;
615     gmx_fio_lock(fio);
616     ret = ret && do_xdr(fio, item, n, eioNRVEC, desc, srcfile, line);
617     gmx_fio_unlock(fio);
618     return ret;
619 }
620
621
622
623 gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
624                            const char *desc, const char *srcfile, int line)
625 {
626     gmx_bool ret = TRUE;
627     int      i;
628     gmx_fio_lock(fio);
629     for (i = 0; i < n; i++)
630     {
631         ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc,
632                             srcfile, line);
633     }
634     gmx_fio_unlock(fio);
635     return ret;
636 }
637
638
639
640 gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
641                              const char *desc, const char *srcfile, int line)
642 {
643     gmx_bool ret = TRUE;
644     int      i;
645     gmx_fio_lock(fio);
646     for (i = 0; i < n; i++)
647     {
648         ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc,
649                             srcfile, line);
650     }
651     gmx_fio_unlock(fio);
652     return ret;
653 }