2 * This file is part of the GROMACS molecular simulation package.
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,2016,2017,2018,2019, 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.
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.
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.
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.
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.
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.
39 #include "gmxfio_xdr.h"
44 #include "gromacs/fileio/gmxfio.h"
45 #include "gromacs/fileio/xdrf.h"
46 #include "gromacs/utility/fatalerror.h"
47 #include "gromacs/utility/gmxassert.h"
48 #include "gromacs/utility/smalloc.h"
50 #include "gmxfio_impl.h"
52 /* Enumerated for data types in files */
54 eioREAL, eioFLOAT, eioDOUBLE, eioINT, eioINT64,
55 eioUCHAR, eioNUCHAR, eioUSHORT,
56 eioRVEC, eioNRVEC, eioIVEC, eioSTRING, eioNR
59 static const char *eioNames[eioNR] =
61 "REAL", "FLOAT", "DOUBLE", "INT", "INT64",
62 "UCHAR", "NUCHAR", "USHORT",
63 "RVEC", "NRVEC", "IVEC", "STRING"
66 void gmx_fio_setprecision(t_fileio *fio, gmx_bool bDouble)
69 fio->bDouble = bDouble;
73 XDR *gmx_fio_getxdr(t_fileio *fio)
77 GMX_RELEASE_ASSERT( fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
83 /* check the number of items given against the type */
84 static void gmx_fio_check_nitem(int eio, int nitem, const char *file, int line)
86 if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR)))
89 "nitem (%d) may differ from 1 only for %s or %s, not for %s"
90 "(%s, %d)", nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC],
91 eioNames[eio], file, line);
95 /* output a data type error. */
97 static void gmx_fio_fe(t_fileio *fio, int eio, const char *desc,
98 const char *srcfile, int line)
100 gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d",
101 fio->bRead ? "read" : "write", desc, eio,
102 ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
106 /* This is the part that reads xdr files. */
108 static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio,
109 const char *desc, const char *srcfile, int line)
111 unsigned char ucdum, *ucptr;
115 int j, m, *iptr, idum;
122 GMX_RELEASE_ASSERT( fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
123 gmx_fio_check_nitem(eio, nitem, srcfile, line);
129 if (item && !fio->bRead)
131 d = *(static_cast<real *>(item));
133 res = xdr_double(fio->xdr, &d);
136 *(static_cast<real *>(item)) = d;
141 if (item && !fio->bRead)
143 f = *(static_cast<real *>(item));
145 res = xdr_float(fio->xdr, &f);
148 *(static_cast<real *>(item)) = f;
153 if (item && !fio->bRead)
155 f = *(static_cast<float *>(item));
157 res = xdr_float(fio->xdr, &f);
160 *(static_cast<float *>(item)) = f;
164 if (item && !fio->bRead)
166 d = *(static_cast<double *>(item));
168 res = xdr_double(fio->xdr, &d);
171 *(static_cast<double *>(item)) = d;
175 if (item && !fio->bRead)
177 idum = *static_cast<int *>(item);
179 res = xdr_int(fio->xdr, &idum);
182 *static_cast<int *>(item) = idum;
186 if (item && !fio->bRead)
188 sdum = *static_cast<int64_t *>(item);
190 res = xdr_int64(fio->xdr, &sdum);
193 *static_cast<int64_t *>(item) = sdum;
197 if (item && !fio->bRead)
199 ucdum = *static_cast<unsigned char *>(item);
201 res = xdr_u_char(fio->xdr, &ucdum);
204 *static_cast<unsigned char *>(item) = ucdum;
208 ucptr = static_cast<unsigned char *>(item);
210 for (j = 0; (j < nitem) && res; j++)
212 res = xdr_u_char(fio->xdr, &(ucptr[j]));
216 if (item && !fio->bRead)
218 us = *static_cast<unsigned short *>(item);
220 res = xdr_u_short(fio->xdr, &us);
223 *static_cast<unsigned short *>(item) = us;
229 if (item && !fio->bRead)
231 for (m = 0; (m < DIM); m++)
233 dvec[m] = (static_cast<real *>(item))[m];
236 res = xdr_vector(fio->xdr, reinterpret_cast<char *>(dvec), DIM,
237 static_cast<unsigned int>(sizeof(double)),
238 reinterpret_cast<xdrproc_t>(xdr_double));
241 for (m = 0; (m < DIM); m++)
243 (static_cast<real *>(item))[m] = dvec[m];
249 if (item && !fio->bRead)
251 for (m = 0; (m < DIM); m++)
253 fvec[m] = (static_cast<real *>(item))[m];
256 res = xdr_vector(fio->xdr, reinterpret_cast<char *>(fvec), DIM,
257 static_cast<unsigned int>(sizeof(float)),
258 reinterpret_cast<xdrproc_t>(xdr_float));
261 for (m = 0; (m < DIM); m++)
263 (static_cast<real *>(item))[m] = fvec[m];
271 for (j = 0; (j < nitem) && res; j++)
275 ptr = (static_cast<rvec *>(item))[j];
277 res = static_cast<bool_t>(do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line));
281 iptr = static_cast<int *>(item);
283 for (m = 0; (m < DIM) && res; m++)
285 if (item && !fio->bRead)
289 res = xdr_int(fio->xdr, &idum);
305 slen = strlen(static_cast<char *>(item)) + 1;
317 if (xdr_int(fio->xdr, &slen) <= 0)
319 gmx_fatal(FARGS, "wrong string length %d for string %s"
320 " (source %s, line %d)", slen, desc, srcfile, line);
322 if (!item && fio->bRead)
328 cptr = static_cast<char *>(item);
332 res = xdr_string(fio->xdr, &cptr, slen);
338 if (!item && fio->bRead)
345 gmx_fio_fe(fio, eio, desc, srcfile, line);
351 /*******************************************************************
353 * READ/WRITE FUNCTIONS
355 *******************************************************************/
357 gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item,
358 const char *desc, const char *srcfile, int line)
361 void *it = const_cast<char*>(item); /* ugh.. */
363 ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line);
368 gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item,
369 const char *desc, const char *srcfile, int line)
373 ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line);
379 gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item,
380 const char *desc, const char *srcfile, int line)
384 ret = do_xdr(fio, item, 1, eioFLOAT, desc, srcfile, line);
389 gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item,
390 const char *desc, const char *srcfile, int line)
394 ret = do_xdr(fio, item, 1, eioDOUBLE, desc, srcfile, line);
400 gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item,
401 const char *desc, const char *srcfile, int line)
409 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
414 int itmp = static_cast<int>(*item);
415 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
421 gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item,
422 const char *desc, const char *srcfile, int line)
426 ret = do_xdr(fio, item, 1, eioINT, desc, srcfile, line);
431 gmx_bool gmx_fio_doe_int64(t_fileio *fio, int64_t *item,
432 const char *desc, const char *srcfile, int line)
436 ret = do_xdr(fio, item, 1, eioINT64, desc, srcfile, line);
441 gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
442 const char *desc, const char *srcfile, int line)
446 ret = do_xdr(fio, item, 1, eioUCHAR, desc, srcfile, line);
451 gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
452 const char *desc, const char *srcfile, int line)
456 ret = do_xdr(fio, item, 1, eioUSHORT, desc, srcfile, line);
461 gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
462 const char *desc, const char *srcfile, int line)
466 ret = do_xdr(fio, item, 1, eioRVEC, desc, srcfile, line);
471 gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
472 const char *desc, const char *srcfile, int line)
476 ret = do_xdr(fio, item, 1, eioIVEC, desc, srcfile, line);
481 gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item,
482 const char *desc, const char *srcfile, int line)
486 ret = do_xdr(fio, item, 1, eioSTRING, desc, srcfile, line);
492 /* Array reading & writing */
494 gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
495 const char *desc, const char *srcfile, int line)
500 for (i = 0; i < n; i++)
502 ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc,
511 gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n,
512 const char *desc, const char *srcfile, int line)
517 for (i = 0; i < n; i++)
519 ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc,
528 gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
529 const char *desc, const char *srcfile, int line)
534 for (i = 0; i < n; i++)
536 ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc,
545 gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n,
546 const char *desc, const char *srcfile, int line)
552 for (i = 0; i < n; i++)
557 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
558 item[i] = (itmp != 0);
562 int itmp = static_cast<int>(item[i]);
563 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
570 gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
571 const char *desc, const char *srcfile, int line)
576 for (i = 0; i < n; i++)
578 ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc,
587 gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, int64_t *item, int n,
588 const char *desc, const char *srcfile, int line)
593 for (i = 0; i < n; i++)
595 ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc,
604 gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
605 const char *desc, const char *srcfile, int line)
609 ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc,
617 gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
618 const char *desc, const char *srcfile, int line)
623 for (i = 0; i < n; i++)
625 ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc,
634 gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
635 const char *desc, const char *srcfile, int line)
639 ret = ret && do_xdr(fio, item, n, eioNRVEC, desc, srcfile, line);
646 gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
647 const char *desc, const char *srcfile, int line)
652 for (i = 0; i < n; i++)
654 ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc,
663 gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
664 const char *desc, const char *srcfile, int line)
669 for (i = 0; i < n; i++)
671 ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc,
681 bool FileIOXdrSerializer::reading() const
686 void FileIOXdrSerializer::doBool(bool *value)
689 gmx_fio_do_gmx_bool(fio_, v);
693 void FileIOXdrSerializer::doUChar(unsigned char *value)
695 gmx_fio_do_uchar(fio_, *value);
698 void FileIOXdrSerializer::doInt(int *value)
700 gmx_fio_do_int(fio_, *value);
703 void FileIOXdrSerializer::doInt64(int64_t *value)
705 gmx_fio_do_int64(fio_, *value);
708 void FileIOXdrSerializer::doFloat(float *value)
710 gmx_fio_do_float(fio_, *value);
713 void FileIOXdrSerializer::doDouble(double *value)
715 gmx_fio_do_double(fio_, *value);
718 void FileIOXdrSerializer::doString(std::string *value)
720 // TODO: Use an arbitrary length buffer (but that is not supported in
725 std::strncpy(buf, value->c_str(), STRLEN);
728 gmx_fio_do_string(fio_, buf);