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