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 */
73 static const char* eioNames[eioNR] = { "REAL", "FLOAT", "DOUBLE", "INT", "INT32",
74 "INT64", "UCHAR", "CHAR", "NCHAR", "NUCHAR",
75 "USHORT", "RVEC", "NRVEC", "IVEC", "STRING" };
77 void gmx_fio_setprecision(t_fileio* fio, gmx_bool bDouble)
80 fio->bDouble = bDouble;
84 bool gmx_fio_is_double(t_fileio* fio)
86 bool isDouble = false;
88 isDouble = fio->bDouble;
93 XDR* gmx_fio_getxdr(t_fileio* fio)
97 GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
103 /* check the number of items given against the type */
104 static void gmx_fio_check_nitem(int eio, int nitem, const char* file, int line)
106 if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR) || (eio == eioNCHAR)))
109 "nitem (%d) may differ from 1 only for %s, %s or %s, not for %s"
111 nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC], eioNames[eioNCHAR], eioNames[eio],
116 /* output a data type error. */
117 [[noreturn]] static void gmx_fio_fe(t_fileio* fio, int eio, const char* desc, const char* srcfile, int line)
119 gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d", fio->bRead ? "read" : "write",
120 desc, eio, ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown", srcfile, line);
123 /* This is the part that reads xdr files. */
125 static gmx_bool do_xdr(t_fileio* fio, void* item, int nitem, int eio, const char* desc, const char* srcfile, int line)
127 unsigned char ucdum, *ucptr;
132 int j, m, *iptr, idum;
140 GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
141 gmx_fio_check_nitem(eio, nitem, srcfile, line);
147 if (item && !fio->bRead)
149 d = *(static_cast<real*>(item));
151 res = xdr_double(fio->xdr, &d);
154 *(static_cast<real*>(item)) = d;
159 if (item && !fio->bRead)
161 f = *(static_cast<real*>(item));
163 res = xdr_float(fio->xdr, &f);
166 *(static_cast<real*>(item)) = f;
171 if (item && !fio->bRead)
173 f = *(static_cast<float*>(item));
175 res = xdr_float(fio->xdr, &f);
178 *(static_cast<float*>(item)) = f;
182 if (item && !fio->bRead)
184 d = *(static_cast<double*>(item));
186 res = xdr_double(fio->xdr, &d);
189 *(static_cast<double*>(item)) = d;
193 if (item && !fio->bRead)
195 idum = *static_cast<int*>(item);
197 res = xdr_int(fio->xdr, &idum);
200 *static_cast<int*>(item) = idum;
204 if (item && !fio->bRead)
206 s32dum = *static_cast<int32_t*>(item);
208 res = xdr_int32(fio->xdr, &s32dum);
211 *static_cast<int32_t*>(item) = s32dum;
215 if (item && !fio->bRead)
217 s64dum = *static_cast<int64_t*>(item);
219 res = xdr_int64(fio->xdr, &s64dum);
222 *static_cast<int64_t*>(item) = s64dum;
226 if (item && !fio->bRead)
228 ucdum = *static_cast<unsigned char*>(item);
230 res = xdr_u_char(fio->xdr, &ucdum);
233 *static_cast<unsigned char*>(item) = ucdum;
237 if (item && !fio->bRead)
239 cdum = *static_cast<char*>(item);
241 res = xdr_char(fio->xdr, &cdum);
244 *static_cast<char*>(item) = cdum;
248 cptr = static_cast<char*>(item);
249 res = xdr_vector(fio->xdr, cptr, nitem, static_cast<unsigned int>(sizeof(char)),
250 reinterpret_cast<xdrproc_t>(xdr_char));
253 ucptr = static_cast<unsigned char*>(item);
254 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(ucptr), nitem,
255 static_cast<unsigned int>(sizeof(unsigned char)),
256 reinterpret_cast<xdrproc_t>(xdr_u_char));
259 if (item && !fio->bRead)
261 us = *static_cast<unsigned short*>(item);
263 res = xdr_u_short(fio->xdr, &us);
266 *static_cast<unsigned short*>(item) = us;
272 if (item && !fio->bRead)
274 for (m = 0; (m < DIM); m++)
276 dvec[m] = (static_cast<real*>(item))[m];
279 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(dvec), DIM,
280 static_cast<unsigned int>(sizeof(double)),
281 reinterpret_cast<xdrproc_t>(xdr_double));
284 for (m = 0; (m < DIM); m++)
286 (static_cast<real*>(item))[m] = dvec[m];
292 if (item && !fio->bRead)
294 for (m = 0; (m < DIM); m++)
296 fvec[m] = (static_cast<real*>(item))[m];
299 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(fvec), DIM,
300 static_cast<unsigned int>(sizeof(float)),
301 reinterpret_cast<xdrproc_t>(xdr_float));
304 for (m = 0; (m < DIM); m++)
306 (static_cast<real*>(item))[m] = fvec[m];
314 for (j = 0; (j < nitem) && res; j++)
318 ptr = (static_cast<rvec*>(item))[j];
320 res = static_cast<bool_t>(do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line));
324 iptr = static_cast<int*>(item);
326 for (m = 0; (m < DIM) && res; m++)
328 if (item && !fio->bRead)
332 res = xdr_int(fio->xdr, &idum);
348 slen = strlen(static_cast<char*>(item)) + 1;
360 if (xdr_int(fio->xdr, &slen) <= 0)
363 "wrong string length %d for string %s"
364 " (source %s, line %d)",
365 slen, desc, srcfile, line);
367 if (!item && fio->bRead)
373 cptr = static_cast<char*>(item);
377 res = xdr_string(fio->xdr, &cptr, slen);
383 if (!item && fio->bRead)
389 default: gmx_fio_fe(fio, eio, desc, srcfile, line);
395 /*******************************************************************
397 * READ/WRITE FUNCTIONS
399 *******************************************************************/
401 gmx_bool gmx_fio_writee_string(t_fileio* fio, const char* item, const char* desc, const char* srcfile, int line)
404 void* it = const_cast<char*>(item); /* ugh.. */
406 ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line);
411 gmx_bool gmx_fio_doe_real(t_fileio* fio, real* item, const char* desc, const char* srcfile, int line)
415 ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line);
420 gmx_bool gmx_fio_doe_float(t_fileio* fio, float* item, const char* desc, const char* srcfile, int line)
424 ret = do_xdr(fio, item, 1, eioFLOAT, desc, srcfile, line);
429 gmx_bool gmx_fio_doe_double(t_fileio* fio, double* item, const char* desc, const char* srcfile, int line)
433 ret = do_xdr(fio, item, 1, eioDOUBLE, desc, srcfile, line);
439 gmx_bool gmx_fio_doe_gmx_bool(t_fileio* fio, gmx_bool* item, const char* desc, const char* srcfile, int line)
447 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
452 int itmp = static_cast<int>(*item);
453 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
459 gmx_bool gmx_fio_doe_int(t_fileio* fio, int* item, const char* desc, const char* srcfile, int line)
463 ret = do_xdr(fio, item, 1, eioINT, desc, srcfile, line);
468 gmx_bool gmx_fio_doe_int32(t_fileio* fio, int32_t* item, const char* desc, const char* srcfile, int line)
472 ret = do_xdr(fio, item, 1, eioINT32, desc, srcfile, line);
477 gmx_bool gmx_fio_doe_int64(t_fileio* fio, int64_t* item, const char* desc, const char* srcfile, int line)
481 ret = do_xdr(fio, item, 1, eioINT64, desc, srcfile, line);
486 gmx_bool gmx_fio_doe_uchar(t_fileio* fio, unsigned char* item, const char* desc, const char* srcfile, int line)
490 ret = do_xdr(fio, item, 1, eioUCHAR, desc, srcfile, line);
495 gmx_bool gmx_fio_doe_char(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line)
499 ret = do_xdr(fio, item, 1, eioCHAR, desc, srcfile, line);
504 gmx_bool gmx_fio_doe_ushort(t_fileio* fio, unsigned short* item, const char* desc, const char* srcfile, int line)
508 ret = do_xdr(fio, item, 1, eioUSHORT, desc, srcfile, line);
513 gmx_bool gmx_fio_doe_rvec(t_fileio* fio, rvec* item, const char* desc, const char* srcfile, int line)
517 ret = do_xdr(fio, item, 1, eioRVEC, desc, srcfile, line);
522 gmx_bool gmx_fio_doe_ivec(t_fileio* fio, ivec* item, const char* desc, const char* srcfile, int line)
526 ret = do_xdr(fio, item, 1, eioIVEC, desc, srcfile, line);
531 gmx_bool gmx_fio_doe_string(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line)
535 ret = do_xdr(fio, item, 1, eioSTRING, desc, srcfile, line);
541 /* Array reading & writing */
543 gmx_bool gmx_fio_ndoe_real(t_fileio* fio, real* item, int n, const char* desc, const char* srcfile, int line)
548 for (i = 0; i < n; i++)
550 ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc, srcfile, line);
557 gmx_bool gmx_fio_ndoe_float(t_fileio* fio, float* item, int n, const char* desc, const char* srcfile, int line)
562 for (i = 0; i < n; i++)
564 ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc, srcfile, line);
571 gmx_bool gmx_fio_ndoe_double(t_fileio* fio, double* item, int n, const char* desc, const char* srcfile, int line)
576 for (i = 0; i < n; i++)
578 ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc, srcfile, line);
585 gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio* fio, gmx_bool* item, int n, const char* desc, const char* srcfile, int line)
591 for (i = 0; i < n; i++)
596 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
597 item[i] = (itmp != 0);
601 int itmp = static_cast<int>(item[i]);
602 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
609 gmx_bool gmx_fio_ndoe_int(t_fileio* fio, int* item, int n, const char* desc, const char* srcfile, int line)
614 for (i = 0; i < n; i++)
616 ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc, srcfile, line);
623 gmx_bool gmx_fio_ndoe_int64(t_fileio* fio, int64_t* item, int n, const char* desc, const char* srcfile, int line)
628 for (i = 0; i < n; i++)
630 ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc, srcfile, line);
637 gmx_bool gmx_fio_ndoe_uchar(t_fileio* fio, unsigned char* item, int n, const char* desc, const char* srcfile, int line)
641 ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc, srcfile, line);
646 gmx_bool gmx_fio_ndoe_char(t_fileio* fio, char* item, int n, const char* desc, const char* srcfile, int line)
650 ret = ret && do_xdr(fio, item, n, eioNCHAR, desc, srcfile, line);
656 gmx_bool gmx_fio_ndoe_ushort(t_fileio* fio, unsigned short* item, int n, const char* desc, const char* srcfile, int line)
661 for (i = 0; i < n; i++)
663 ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc, srcfile, line);
670 gmx_bool gmx_fio_ndoe_rvec(t_fileio* fio, rvec* item, int n, const char* desc, const char* srcfile, int line)
674 ret = ret && do_xdr(fio, item, n, eioNRVEC, desc, srcfile, line);
680 gmx_bool gmx_fio_ndoe_ivec(t_fileio* fio, ivec* item, int n, const char* desc, const char* srcfile, int line)
685 for (i = 0; i < n; i++)
687 ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc, srcfile, line);
694 gmx_bool gmx_fio_ndoe_string(t_fileio* fio, char* item[], int n, const char* desc, const char* srcfile, int line)
699 for (i = 0; i < n; i++)
701 ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc, srcfile, line);
710 FileIOXdrSerializer::FileIOXdrSerializer(t_fileio* fio) : fio_(fio)
712 GMX_RELEASE_ASSERT(fio, "Need valid file io handle");
715 bool FileIOXdrSerializer::reading() const
720 void FileIOXdrSerializer::doBool(bool* value)
722 gmx_fio_do_gmx_bool(fio_, *value);
725 void FileIOXdrSerializer::doUChar(unsigned char* value)
727 gmx_fio_do_uchar(fio_, *value);
730 void FileIOXdrSerializer::doChar(char* value)
732 gmx_fio_do_char(fio_, *value);
735 void FileIOXdrSerializer::doUShort(unsigned short* value)
737 gmx_fio_do_ushort(fio_, *value);
740 void FileIOXdrSerializer::doInt(int* value)
742 gmx_fio_do_int(fio_, *value);
745 void FileIOXdrSerializer::doInt32(int32_t* value)
747 gmx_fio_do_int32(fio_, *value);
750 void FileIOXdrSerializer::doInt64(int64_t* value)
752 gmx_fio_do_int64(fio_, *value);
755 void FileIOXdrSerializer::doFloat(float* value)
757 gmx_fio_do_float(fio_, *value);
760 void FileIOXdrSerializer::doDouble(double* value)
762 gmx_fio_do_double(fio_, *value);
765 void FileIOXdrSerializer::doReal(real* value)
767 gmx_fio_do_real(fio_, *value);
770 void FileIOXdrSerializer::doIvec(ivec* value)
772 gmx_fio_do_ivec(fio_, *value);
775 void FileIOXdrSerializer::doRvec(rvec* value)
777 gmx_fio_do_rvec(fio_, *value);
780 void FileIOXdrSerializer::doCharArray(char* values, int elements)
782 gmx_fio_ndo_char(fio_, values, elements);
785 void FileIOXdrSerializer::doUCharArray(unsigned char* values, int elements)
787 gmx_fio_ndo_uchar(fio_, values, elements);
790 void FileIOXdrSerializer::doRvecArray(rvec* values, int elements)
792 gmx_fio_ndo_rvec(fio_, values, elements);
795 void FileIOXdrSerializer::doString(std::string* value)
797 // TODO: Use an arbitrary length buffer (but that is not supported in
802 std::strncpy(buf, value->c_str(), STRLEN);
805 gmx_fio_do_string(fio_, buf);