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,2016,2017 by the GROMACS development team.
7 * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
8 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9 * and including many others, as listed in the AUTHORS file in the
10 * top-level source directory and at http://www.gromacs.org.
11 *
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
16 *
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
34 *
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
37 */
38 #include "gmxpre.h"
39
40 #include "gmxfio_xdr.h"
41
42 #include <cstddef>
43 #include <cstdio>
44 #include <cstring>
45
46 #include <limits>
47
48 #include "gromacs/fileio/gmxfio.h"
49 #include "gromacs/fileio/xdrf.h"
50 #include "gromacs/utility/fatalerror.h"
51 #include "gromacs/utility/gmxassert.h"
52 #include "gromacs/utility/smalloc.h"
53
54 #include "gmxfio_impl.h"
55
56 /* Enumerated for data types in files */
57 enum
58 {
59 eioREAL,
60 eioFLOAT,
61 eioDOUBLE,
62 eioINT,
63 eioINT32,
64 eioINT64,
65 eioUCHAR,
66 eioCHAR,
67 eioNCHAR,
68 eioNUCHAR,
69 eioUSHORT,
70 eioRVEC,
71 eioNRVEC,
72 eioIVEC,
73 eioSTRING,
74 eioOPAQUE,
75 eioNR
76 };
77
78 static const char* eioNames[eioNR] = { "REAL", "FLOAT", "DOUBLE", "INT", "INT32", "INT64",
79 "UCHAR", "CHAR", "NCHAR", "NUCHAR", "USHORT", "RVEC",
80 "NRVEC", "IVEC", "STRING", "OPAQUE" };
81
gmx_fio_setprecision(t_fileio * fio,gmx_bool bDouble)82 void gmx_fio_setprecision(t_fileio* fio, gmx_bool bDouble)
83 {
84 gmx_fio_lock(fio);
85 fio->bDouble = bDouble;
86 gmx_fio_unlock(fio);
87 }
88
gmx_fio_is_double(t_fileio * fio)89 bool gmx_fio_is_double(t_fileio* fio)
90 {
91 bool isDouble = false;
92 gmx_fio_lock(fio);
93 isDouble = fio->bDouble;
94 gmx_fio_unlock(fio);
95 return isDouble;
96 }
97
gmx_fio_getxdr(t_fileio * fio)98 XDR* gmx_fio_getxdr(t_fileio* fio)
99 {
100 XDR* ret = nullptr;
101 gmx_fio_lock(fio);
102 GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
103 ret = fio->xdr;
104 gmx_fio_unlock(fio);
105 return ret;
106 }
107
108 /* check the number of items given against the type */
gmx_fio_check_nitem(int eio,std::size_t nitem,const char * file,int line)109 static void gmx_fio_check_nitem(int eio, std::size_t nitem, const char* file, int line)
110 {
111 if ((nitem != 1)
112 && !((eio == eioNRVEC) || (eio == eioNUCHAR) || (eio == eioNCHAR) || (eio == eioOPAQUE)))
113 {
114 gmx_fatal(FARGS,
115 "nitem may differ from 1 only for %s, %s, %s or %s, not for %s"
116 "(%s, %d)",
117 eioNames[eioNUCHAR], eioNames[eioNRVEC], eioNames[eioNCHAR], eioNames[eioOPAQUE],
118 eioNames[eio], file, line);
119 }
120 }
121
122 /* output a data type error. */
gmx_fio_fe(t_fileio * fio,int eio,const char * desc,const char * srcfile,int line)123 [[noreturn]] static void gmx_fio_fe(t_fileio* fio, int eio, const char* desc, const char* srcfile, int line)
124 {
125 gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d", fio->bRead ? "read" : "write",
126 desc, eio, ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown", srcfile, line);
127 }
128
129 /* This is the part that reads xdr files. */
130
131 static gmx_bool
do_xdr(t_fileio * fio,void * item,std::size_t nitem,int eio,const char * desc,const char * srcfile,int line)132 do_xdr(t_fileio* fio, void* item, std::size_t nitem, int eio, const char* desc, const char* srcfile, int line)
133 {
134 unsigned char ucdum, *ucptr;
135 char cdum, *cptr;
136 bool_t res = 0;
137 float fvec[DIM];
138 double dvec[DIM];
139 int m, *iptr, idum;
140 int32_t s32dum;
141 int64_t s64dum;
142 real* ptr;
143 unsigned short us;
144 double d = 0;
145 float f = 0;
146
147 GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers");
148 gmx_fio_check_nitem(eio, nitem, srcfile, line);
149 switch (eio)
150 {
151 case eioREAL:
152 if (fio->bDouble)
153 {
154 if (item && !fio->bRead)
155 {
156 d = *(static_cast<real*>(item));
157 }
158 res = xdr_double(fio->xdr, &d);
159 if (item)
160 {
161 *(static_cast<real*>(item)) = d;
162 }
163 }
164 else
165 {
166 if (item && !fio->bRead)
167 {
168 f = *(static_cast<real*>(item));
169 }
170 res = xdr_float(fio->xdr, &f);
171 if (item)
172 {
173 *(static_cast<real*>(item)) = f;
174 }
175 }
176 break;
177 case eioFLOAT:
178 if (item && !fio->bRead)
179 {
180 f = *(static_cast<float*>(item));
181 }
182 res = xdr_float(fio->xdr, &f);
183 if (item)
184 {
185 *(static_cast<float*>(item)) = f;
186 }
187 break;
188 case eioDOUBLE:
189 if (item && !fio->bRead)
190 {
191 d = *(static_cast<double*>(item));
192 }
193 res = xdr_double(fio->xdr, &d);
194 if (item)
195 {
196 *(static_cast<double*>(item)) = d;
197 }
198 break;
199 case eioINT:
200 if (item && !fio->bRead)
201 {
202 idum = *static_cast<int*>(item);
203 }
204 res = xdr_int(fio->xdr, &idum);
205 if (item)
206 {
207 *static_cast<int*>(item) = idum;
208 }
209 break;
210 case eioINT32:
211 if (item && !fio->bRead)
212 {
213 s32dum = *static_cast<int32_t*>(item);
214 }
215 res = xdr_int32(fio->xdr, &s32dum);
216 if (item)
217 {
218 *static_cast<int32_t*>(item) = s32dum;
219 }
220 break;
221 case eioINT64:
222 if (item && !fio->bRead)
223 {
224 s64dum = *static_cast<int64_t*>(item);
225 }
226 res = xdr_int64(fio->xdr, &s64dum);
227 if (item)
228 {
229 *static_cast<int64_t*>(item) = s64dum;
230 }
231 break;
232 case eioUCHAR:
233 if (item && !fio->bRead)
234 {
235 ucdum = *static_cast<unsigned char*>(item);
236 }
237 res = xdr_u_char(fio->xdr, &ucdum);
238 if (item)
239 {
240 *static_cast<unsigned char*>(item) = ucdum;
241 }
242 break;
243 case eioCHAR:
244 if (item && !fio->bRead)
245 {
246 cdum = *static_cast<char*>(item);
247 }
248 res = xdr_char(fio->xdr, &cdum);
249 if (item)
250 {
251 *static_cast<char*>(item) = cdum;
252 }
253 break;
254 case eioNCHAR:
255 cptr = static_cast<char*>(item);
256 GMX_RELEASE_ASSERT(nitem < static_cast<std::size_t>(std::numeric_limits<int>::max()),
257 "The XDR interface cannot handle array lengths > 2^31");
258 res = xdr_vector(fio->xdr, cptr, static_cast<int>(nitem),
259 static_cast<unsigned int>(sizeof(char)),
260 reinterpret_cast<xdrproc_t>(xdr_char));
261 break;
262 case eioNUCHAR:
263 ucptr = static_cast<unsigned char*>(item);
264 GMX_RELEASE_ASSERT(nitem < static_cast<std::size_t>(std::numeric_limits<int>::max()),
265 "The XDR interface cannot handle array lengths > 2^31");
266 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(ucptr), static_cast<int>(nitem),
267 static_cast<unsigned int>(sizeof(unsigned char)),
268 reinterpret_cast<xdrproc_t>(xdr_u_char));
269 break;
270 case eioUSHORT:
271 if (item && !fio->bRead)
272 {
273 us = *static_cast<unsigned short*>(item);
274 }
275 res = xdr_u_short(fio->xdr, &us);
276 if (item)
277 {
278 *static_cast<unsigned short*>(item) = us;
279 }
280 break;
281 case eioRVEC:
282 if (fio->bDouble)
283 {
284 if (item && !fio->bRead)
285 {
286 for (m = 0; (m < DIM); m++)
287 {
288 dvec[m] = (static_cast<real*>(item))[m];
289 }
290 }
291 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(dvec), DIM,
292 static_cast<unsigned int>(sizeof(double)),
293 reinterpret_cast<xdrproc_t>(xdr_double));
294 if (item)
295 {
296 for (m = 0; (m < DIM); m++)
297 {
298 (static_cast<real*>(item))[m] = dvec[m];
299 }
300 }
301 }
302 else
303 {
304 if (item && !fio->bRead)
305 {
306 for (m = 0; (m < DIM); m++)
307 {
308 fvec[m] = (static_cast<real*>(item))[m];
309 }
310 }
311 res = xdr_vector(fio->xdr, reinterpret_cast<char*>(fvec), DIM,
312 static_cast<unsigned int>(sizeof(float)),
313 reinterpret_cast<xdrproc_t>(xdr_float));
314 if (item)
315 {
316 for (m = 0; (m < DIM); m++)
317 {
318 (static_cast<real*>(item))[m] = fvec[m];
319 }
320 }
321 }
322 break;
323 case eioNRVEC:
324 ptr = nullptr;
325 res = 1;
326 for (std::size_t j = 0; j < nitem && res; j++)
327 {
328 if (item)
329 {
330 ptr = (static_cast<rvec*>(item))[j];
331 }
332 res = static_cast<bool_t>(do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line));
333 }
334 break;
335 case eioIVEC:
336 iptr = static_cast<int*>(item);
337 res = 1;
338 for (m = 0; (m < DIM) && res; m++)
339 {
340 if (item && !fio->bRead)
341 {
342 idum = iptr[m];
343 }
344 res = xdr_int(fio->xdr, &idum);
345 if (item)
346 {
347 iptr[m] = idum;
348 }
349 }
350 break;
351 case eioSTRING:
352 {
353 char* cptr;
354 int slen;
355
356 if (item)
357 {
358 if (!fio->bRead)
359 {
360 slen = strlen(static_cast<char*>(item)) + 1;
361 }
362 else
363 {
364 slen = 0;
365 }
366 }
367 else
368 {
369 slen = 0;
370 }
371
372 if (xdr_int(fio->xdr, &slen) <= 0)
373 {
374 gmx_fatal(FARGS,
375 "wrong string length %d for string %s"
376 " (source %s, line %d)",
377 slen, desc, srcfile, line);
378 }
379 if (!item && fio->bRead)
380 {
381 snew(cptr, slen);
382 }
383 else
384 {
385 cptr = static_cast<char*>(item);
386 }
387 if (cptr)
388 {
389 res = xdr_string(fio->xdr, &cptr, slen);
390 }
391 else
392 {
393 res = 1;
394 }
395 if (!item && fio->bRead)
396 {
397 sfree(cptr);
398 }
399 break;
400 }
401 case eioOPAQUE:
402 {
403 if (item == nullptr && nitem > 0)
404 {
405 gmx_fatal(FARGS, "Null pointer provided for non-zero length XDR opaque data.");
406 }
407
408 if (nitem > 0)
409 {
410 // We need to support very large opaque data objects although the default
411 // XDR interface only uses integers for the size field, since gromacs-2020
412 // e.g. embeds the entire TPR body as a single such object, which would break all
413 // TPR files larger than 2GB unless we handle it as a special case.
414 // To avoid inserting extra padding, we calculate the chunk size as:
415 // - The max value of a signed integer + 1
416 // - Subtract 4 (the XDR object size) to get a size within the range of the signed int.
417 const std::size_t maxChunk =
418 static_cast<std::size_t>(std::numeric_limits<int>::max()) + 1 - 4;
419
420 for (res = 1; res > 0 && nitem > 0;)
421 {
422 std::size_t thisChunk = std::min(maxChunk, nitem);
423 res = xdr_opaque(fio->xdr, reinterpret_cast<char*>(item), thisChunk);
424 nitem -= thisChunk;
425 }
426 }
427 else
428 {
429 res = 1;
430 }
431 break;
432 }
433 default: gmx_fio_fe(fio, eio, desc, srcfile, line);
434 }
435
436 return (res != 0);
437 }
438
439 /*******************************************************************
440 *
441 * READ/WRITE FUNCTIONS
442 *
443 *******************************************************************/
444
gmx_fio_writee_string(t_fileio * fio,const char * item,const char * desc,const char * srcfile,int line)445 gmx_bool gmx_fio_writee_string(t_fileio* fio, const char* item, const char* desc, const char* srcfile, int line)
446 {
447 gmx_bool ret;
448 void* it = const_cast<char*>(item); /* ugh.. */
449 gmx_fio_lock(fio);
450 ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line);
451 gmx_fio_unlock(fio);
452 return ret;
453 }
454
gmx_fio_doe_real(t_fileio * fio,real * item,const char * desc,const char * srcfile,int line)455 gmx_bool gmx_fio_doe_real(t_fileio* fio, real* item, const char* desc, const char* srcfile, int line)
456 {
457 gmx_bool ret;
458 gmx_fio_lock(fio);
459 ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line);
460 gmx_fio_unlock(fio);
461 return ret;
462 }
463
gmx_fio_doe_float(t_fileio * fio,float * item,const char * desc,const char * srcfile,int line)464 gmx_bool gmx_fio_doe_float(t_fileio* fio, float* item, const char* desc, const char* srcfile, int line)
465 {
466 gmx_bool ret;
467 gmx_fio_lock(fio);
468 ret = do_xdr(fio, item, 1, eioFLOAT, desc, srcfile, line);
469 gmx_fio_unlock(fio);
470 return ret;
471 }
472
gmx_fio_doe_double(t_fileio * fio,double * item,const char * desc,const char * srcfile,int line)473 gmx_bool gmx_fio_doe_double(t_fileio* fio, double* item, const char* desc, const char* srcfile, int line)
474 {
475 gmx_bool ret;
476 gmx_fio_lock(fio);
477 ret = do_xdr(fio, item, 1, eioDOUBLE, desc, srcfile, line);
478 gmx_fio_unlock(fio);
479 return ret;
480 }
481
482
gmx_fio_doe_gmx_bool(t_fileio * fio,gmx_bool * item,const char * desc,const char * srcfile,int line)483 gmx_bool gmx_fio_doe_gmx_bool(t_fileio* fio, gmx_bool* item, const char* desc, const char* srcfile, int line)
484 {
485 gmx_bool ret;
486
487 gmx_fio_lock(fio);
488 if (fio->bRead)
489 {
490 int itmp = 0;
491 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
492 *item = (itmp != 0);
493 }
494 else
495 {
496 int itmp = static_cast<int>(*item);
497 ret = do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
498 }
499 gmx_fio_unlock(fio);
500 return ret;
501 }
502
gmx_fio_doe_int(t_fileio * fio,int * item,const char * desc,const char * srcfile,int line)503 gmx_bool gmx_fio_doe_int(t_fileio* fio, int* item, const char* desc, const char* srcfile, int line)
504 {
505 gmx_bool ret;
506 gmx_fio_lock(fio);
507 ret = do_xdr(fio, item, 1, eioINT, desc, srcfile, line);
508 gmx_fio_unlock(fio);
509 return ret;
510 }
511
gmx_fio_doe_int32(t_fileio * fio,int32_t * item,const char * desc,const char * srcfile,int line)512 gmx_bool gmx_fio_doe_int32(t_fileio* fio, int32_t* item, const char* desc, const char* srcfile, int line)
513 {
514 gmx_bool ret;
515 gmx_fio_lock(fio);
516 ret = do_xdr(fio, item, 1, eioINT32, desc, srcfile, line);
517 gmx_fio_unlock(fio);
518 return ret;
519 }
520
gmx_fio_doe_int64(t_fileio * fio,int64_t * item,const char * desc,const char * srcfile,int line)521 gmx_bool gmx_fio_doe_int64(t_fileio* fio, int64_t* item, const char* desc, const char* srcfile, int line)
522 {
523 gmx_bool ret;
524 gmx_fio_lock(fio);
525 ret = do_xdr(fio, item, 1, eioINT64, desc, srcfile, line);
526 gmx_fio_unlock(fio);
527 return ret;
528 }
529
gmx_fio_doe_uchar(t_fileio * fio,unsigned char * item,const char * desc,const char * srcfile,int line)530 gmx_bool gmx_fio_doe_uchar(t_fileio* fio, unsigned char* item, const char* desc, const char* srcfile, int line)
531 {
532 gmx_bool ret;
533 gmx_fio_lock(fio);
534 ret = do_xdr(fio, item, 1, eioUCHAR, desc, srcfile, line);
535 gmx_fio_unlock(fio);
536 return ret;
537 }
538
gmx_fio_doe_char(t_fileio * fio,char * item,const char * desc,const char * srcfile,int line)539 gmx_bool gmx_fio_doe_char(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line)
540 {
541 gmx_bool ret;
542 gmx_fio_lock(fio);
543 ret = do_xdr(fio, item, 1, eioCHAR, desc, srcfile, line);
544 gmx_fio_unlock(fio);
545 return ret;
546 }
547
gmx_fio_doe_ushort(t_fileio * fio,unsigned short * item,const char * desc,const char * srcfile,int line)548 gmx_bool gmx_fio_doe_ushort(t_fileio* fio, unsigned short* item, const char* desc, const char* srcfile, int line)
549 {
550 gmx_bool ret;
551 gmx_fio_lock(fio);
552 ret = do_xdr(fio, item, 1, eioUSHORT, desc, srcfile, line);
553 gmx_fio_unlock(fio);
554 return ret;
555 }
556
gmx_fio_doe_rvec(t_fileio * fio,rvec * item,const char * desc,const char * srcfile,int line)557 gmx_bool gmx_fio_doe_rvec(t_fileio* fio, rvec* item, const char* desc, const char* srcfile, int line)
558 {
559 gmx_bool ret;
560 gmx_fio_lock(fio);
561 ret = do_xdr(fio, item, 1, eioRVEC, desc, srcfile, line);
562 gmx_fio_unlock(fio);
563 return ret;
564 }
565
gmx_fio_doe_ivec(t_fileio * fio,ivec * item,const char * desc,const char * srcfile,int line)566 gmx_bool gmx_fio_doe_ivec(t_fileio* fio, ivec* item, const char* desc, const char* srcfile, int line)
567 {
568 gmx_bool ret;
569 gmx_fio_lock(fio);
570 ret = do_xdr(fio, item, 1, eioIVEC, desc, srcfile, line);
571 gmx_fio_unlock(fio);
572 return ret;
573 }
574
gmx_fio_doe_string(t_fileio * fio,char * item,const char * desc,const char * srcfile,int line)575 gmx_bool gmx_fio_doe_string(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line)
576 {
577 gmx_bool ret;
578 gmx_fio_lock(fio);
579 ret = do_xdr(fio, item, 1, eioSTRING, desc, srcfile, line);
580 gmx_fio_unlock(fio);
581 return ret;
582 }
583
gmx_fio_doe_opaque(t_fileio * fio,char * data,std::size_t size,const char * desc,const char * srcfile,int line)584 gmx_bool gmx_fio_doe_opaque(t_fileio* fio, char* data, std::size_t size, const char* desc, const char* srcfile, int line)
585 {
586 gmx_bool ret;
587 gmx_fio_lock(fio);
588 ret = do_xdr(fio, data, size, eioOPAQUE, desc, srcfile, line);
589 gmx_fio_unlock(fio);
590 return ret;
591 }
592
593 /* Array reading & writing */
594
gmx_fio_ndoe_real(t_fileio * fio,real * item,int n,const char * desc,const char * srcfile,int line)595 gmx_bool gmx_fio_ndoe_real(t_fileio* fio, real* item, int n, 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, eioREAL, desc, srcfile, line);
603 }
604 gmx_fio_unlock(fio);
605 return ret;
606 }
607
608
gmx_fio_ndoe_float(t_fileio * fio,float * item,int n,const char * desc,const char * srcfile,int line)609 gmx_bool gmx_fio_ndoe_float(t_fileio* fio, float* item, int n, const char* desc, const char* srcfile, int line)
610 {
611 gmx_bool ret = TRUE;
612 int i;
613 gmx_fio_lock(fio);
614 for (i = 0; i < n; i++)
615 {
616 ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc, srcfile, line);
617 }
618 gmx_fio_unlock(fio);
619 return ret;
620 }
621
622
gmx_fio_ndoe_double(t_fileio * fio,double * item,int n,const char * desc,const char * srcfile,int line)623 gmx_bool gmx_fio_ndoe_double(t_fileio* fio, double* item, int n, const char* desc, const char* srcfile, int line)
624 {
625 gmx_bool ret = TRUE;
626 int i;
627 gmx_fio_lock(fio);
628 for (i = 0; i < n; i++)
629 {
630 ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc, srcfile, line);
631 }
632 gmx_fio_unlock(fio);
633 return ret;
634 }
635
636
gmx_fio_ndoe_gmx_bool(t_fileio * fio,gmx_bool * item,int n,const char * desc,const char * srcfile,int line)637 gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio* fio, gmx_bool* item, int n, const char* desc, const char* srcfile, int line)
638 {
639 gmx_bool ret = TRUE;
640 int i;
641
642 gmx_fio_lock(fio);
643 for (i = 0; i < n; i++)
644 {
645 if (fio->bRead)
646 {
647 int itmp = 0;
648 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
649 item[i] = (itmp != 0);
650 }
651 else
652 {
653 int itmp = static_cast<int>(item[i]);
654 ret = ret && do_xdr(fio, &itmp, 1, eioINT, desc, srcfile, line);
655 }
656 }
657 gmx_fio_unlock(fio);
658 return ret;
659 }
660
gmx_fio_ndoe_int(t_fileio * fio,int * item,int n,const char * desc,const char * srcfile,int line)661 gmx_bool gmx_fio_ndoe_int(t_fileio* fio, int* item, int n, 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, eioINT, desc, srcfile, line);
669 }
670 gmx_fio_unlock(fio);
671 return ret;
672 }
673
674
gmx_fio_ndoe_int64(t_fileio * fio,int64_t * item,int n,const char * desc,const char * srcfile,int line)675 gmx_bool gmx_fio_ndoe_int64(t_fileio* fio, int64_t* item, int n, const char* desc, const char* srcfile, int line)
676 {
677 gmx_bool ret = TRUE;
678 int i;
679 gmx_fio_lock(fio);
680 for (i = 0; i < n; i++)
681 {
682 ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc, srcfile, line);
683 }
684 gmx_fio_unlock(fio);
685 return ret;
686 }
687
688
gmx_fio_ndoe_uchar(t_fileio * fio,unsigned char * item,int n,const char * desc,const char * srcfile,int line)689 gmx_bool gmx_fio_ndoe_uchar(t_fileio* fio, unsigned char* item, int n, const char* desc, const char* srcfile, int line)
690 {
691 gmx_bool ret = TRUE;
692 gmx_fio_lock(fio);
693 ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc, srcfile, line);
694 gmx_fio_unlock(fio);
695 return ret;
696 }
697
gmx_fio_ndoe_char(t_fileio * fio,char * item,int n,const char * desc,const char * srcfile,int line)698 gmx_bool gmx_fio_ndoe_char(t_fileio* fio, char* item, int n, const char* desc, const char* srcfile, int line)
699 {
700 gmx_bool ret = TRUE;
701 gmx_fio_lock(fio);
702 ret = ret && do_xdr(fio, item, n, eioNCHAR, desc, srcfile, line);
703 gmx_fio_unlock(fio);
704 return ret;
705 }
706
707
gmx_fio_ndoe_ushort(t_fileio * fio,unsigned short * item,int n,const char * desc,const char * srcfile,int line)708 gmx_bool gmx_fio_ndoe_ushort(t_fileio* fio, unsigned short* item, int n, const char* desc, const char* srcfile, int line)
709 {
710 gmx_bool ret = TRUE;
711 int i;
712 gmx_fio_lock(fio);
713 for (i = 0; i < n; i++)
714 {
715 ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc, srcfile, line);
716 }
717 gmx_fio_unlock(fio);
718 return ret;
719 }
720
721
gmx_fio_ndoe_rvec(t_fileio * fio,rvec * item,int n,const char * desc,const char * srcfile,int line)722 gmx_bool gmx_fio_ndoe_rvec(t_fileio* fio, rvec* item, int n, const char* desc, const char* srcfile, int line)
723 {
724 gmx_bool ret = TRUE;
725 gmx_fio_lock(fio);
726 ret = ret && do_xdr(fio, item, n, eioNRVEC, desc, srcfile, line);
727 gmx_fio_unlock(fio);
728 return ret;
729 }
730
731
gmx_fio_ndoe_ivec(t_fileio * fio,ivec * item,int n,const char * desc,const char * srcfile,int line)732 gmx_bool gmx_fio_ndoe_ivec(t_fileio* fio, ivec* item, int n, const char* desc, const char* srcfile, int line)
733 {
734 gmx_bool ret = TRUE;
735 int i;
736 gmx_fio_lock(fio);
737 for (i = 0; i < n; i++)
738 {
739 ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc, srcfile, line);
740 }
741 gmx_fio_unlock(fio);
742 return ret;
743 }
744
745
gmx_fio_ndoe_string(t_fileio * fio,char * item[],int n,const char * desc,const char * srcfile,int line)746 gmx_bool gmx_fio_ndoe_string(t_fileio* fio, char* item[], int n, const char* desc, const char* srcfile, int line)
747 {
748 gmx_bool ret = TRUE;
749 int i;
750 gmx_fio_lock(fio);
751 for (i = 0; i < n; i++)
752 {
753 ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc, srcfile, line);
754 }
755 gmx_fio_unlock(fio);
756 return ret;
757 }
758
759 namespace gmx
760 {
761
FileIOXdrSerializer(t_fileio * fio)762 FileIOXdrSerializer::FileIOXdrSerializer(t_fileio* fio) : fio_(fio)
763 {
764 GMX_RELEASE_ASSERT(fio, "Need valid file io handle");
765 }
766
reading() const767 bool FileIOXdrSerializer::reading() const
768 {
769 return fio_->bRead;
770 }
771
doBool(bool * value)772 void FileIOXdrSerializer::doBool(bool* value)
773 {
774 gmx_fio_do_gmx_bool(fio_, *value);
775 }
776
doUChar(unsigned char * value)777 void FileIOXdrSerializer::doUChar(unsigned char* value)
778 {
779 gmx_fio_do_uchar(fio_, *value);
780 }
781
doChar(char * value)782 void FileIOXdrSerializer::doChar(char* value)
783 {
784 gmx_fio_do_char(fio_, *value);
785 }
786
doUShort(unsigned short * value)787 void FileIOXdrSerializer::doUShort(unsigned short* value)
788 {
789 gmx_fio_do_ushort(fio_, *value);
790 }
791
doInt(int * value)792 void FileIOXdrSerializer::doInt(int* value)
793 {
794 gmx_fio_do_int(fio_, *value);
795 }
796
doInt32(int32_t * value)797 void FileIOXdrSerializer::doInt32(int32_t* value)
798 {
799 gmx_fio_do_int32(fio_, *value);
800 }
801
doInt64(int64_t * value)802 void FileIOXdrSerializer::doInt64(int64_t* value)
803 {
804 gmx_fio_do_int64(fio_, *value);
805 }
806
doFloat(float * value)807 void FileIOXdrSerializer::doFloat(float* value)
808 {
809 gmx_fio_do_float(fio_, *value);
810 }
811
doDouble(double * value)812 void FileIOXdrSerializer::doDouble(double* value)
813 {
814 gmx_fio_do_double(fio_, *value);
815 }
816
doReal(real * value)817 void FileIOXdrSerializer::doReal(real* value)
818 {
819 gmx_fio_do_real(fio_, *value);
820 }
821
doIvec(ivec * value)822 void FileIOXdrSerializer::doIvec(ivec* value)
823 {
824 gmx_fio_do_ivec(fio_, *value);
825 }
826
doRvec(rvec * value)827 void FileIOXdrSerializer::doRvec(rvec* value)
828 {
829 gmx_fio_do_rvec(fio_, *value);
830 }
831
doCharArray(char * values,int elements)832 void FileIOXdrSerializer::doCharArray(char* values, int elements)
833 {
834 gmx_fio_ndo_char(fio_, values, elements);
835 }
836
doUCharArray(unsigned char * values,int elements)837 void FileIOXdrSerializer::doUCharArray(unsigned char* values, int elements)
838 {
839 gmx_fio_ndo_uchar(fio_, values, elements);
840 }
841
doRvecArray(rvec * values,int elements)842 void FileIOXdrSerializer::doRvecArray(rvec* values, int elements)
843 {
844 gmx_fio_ndo_rvec(fio_, values, elements);
845 }
846
doString(std::string * value)847 void FileIOXdrSerializer::doString(std::string* value)
848 {
849 // TODO: Use an arbitrary length buffer (but that is not supported in
850 // gmx_fio, either).
851 char buf[STRLEN];
852 if (!fio_->bRead)
853 {
854 std::strncpy(buf, value->c_str(), STRLEN);
855 buf[STRLEN - 1] = 0;
856 }
857 gmx_fio_do_string(fio_, buf);
858 if (fio_->bRead)
859 {
860 *value = buf;
861 }
862 }
863
doOpaque(char * data,std::size_t size)864 void FileIOXdrSerializer::doOpaque(char* data, std::size_t size)
865 {
866 gmx_fio_do_opaque(fio_, data, size);
867 }
868
869 } // namespace gmx
870