xdr_cxx.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // C/C++ includes
20 #include <cstring>
21 #include <limits>
22 #include <iomanip>
23 #include <sstream>
24 #include <fstream>
25 
26 #include <unistd.h> // for getpid()
27 
28 // Local includes
29 #include "libmesh/xdr_cxx.h"
31 #ifdef LIBMESH_HAVE_GZSTREAM
32 # include "libmesh/ignore_warnings.h" // shadowing in gzstream.h
33 # include "gzstream.h" // For reading/writing compressed streams
35 #endif
36 
37 
38 // Anonymous namespace for implementation details.
39 namespace {
40 
41 // Nasty hacks for reading/writing zipped files
42 void bzip_file (const std::string & unzipped_name)
43 {
44 #ifdef LIBMESH_HAVE_BZIP
45  LOG_SCOPE("system(bzip2)", "XdrIO");
46 
47  std::string system_string = "bzip2 -f ";
48  system_string += unzipped_name;
49  if (std::system(system_string.c_str()))
50  libmesh_file_error(system_string);
51 #else
52  libmesh_error_msg("ERROR: need bzip2/bunzip2 to create " << unzipped_name << ".bz2");
53 #endif
54 }
55 
56 std::string unzip_file (const std::string & name)
57 {
58  std::ostringstream pid_suffix;
59  pid_suffix << '_' << getpid();
60 
61  std::string new_name = name;
62  if (name.size() - name.rfind(".bz2") == 4)
63  {
64 #ifdef LIBMESH_HAVE_BZIP
65  new_name.erase(new_name.end() - 4, new_name.end());
66  new_name += pid_suffix.str();
67  LOG_SCOPE("system(bunzip2)", "XdrIO");
68  std::string system_string = "bunzip2 -f -k -c ";
69  system_string += name + " > " + new_name;
70  if (std::system(system_string.c_str()))
71  libmesh_file_error(system_string);
72 #else
73  libmesh_error_msg("ERROR: need bzip2/bunzip2 to open .bz2 file " << name);
74 #endif
75  }
76  else if (name.size() - name.rfind(".xz") == 3)
77  {
78 #ifdef LIBMESH_HAVE_XZ
79  new_name.erase(new_name.end() - 3, new_name.end());
80  new_name += pid_suffix.str();
81  LOG_SCOPE("system(xz -d)", "XdrIO");
82  std::string system_string = "xz -f -d -k -c ";
83  system_string += name + " > " + new_name;
84  if (std::system(system_string.c_str()))
85  libmesh_file_error(system_string);
86 #else
87  libmesh_error_msg("ERROR: need xz to open .xz file " << name);
88 #endif
89  }
90  return new_name;
91 }
92 
93 void xzip_file (const std::string & unzipped_name)
94 {
95 #ifdef LIBMESH_HAVE_XZ
96  LOG_SCOPE("system(xz)", "XdrIO");
97 
98  std::string system_string = "xz -f ";
99  system_string += unzipped_name;
100  if (std::system(system_string.c_str()))
101  libmesh_file_error(system_string);
102 #else
103  libmesh_error_msg("ERROR: need xz to create " << unzipped_name << ".xz");
104 #endif
105 }
106 
107 
108 // remove an unzipped file
109 void remove_unzipped_file (const std::string & name)
110 {
111  std::ostringstream pid_suffix;
112  pid_suffix << '_' << getpid();
113 
114  // If we temporarily decompressed a file, remove the
115  // uncompressed version
116  if (name.size() - name.rfind(".bz2") == 4)
117  {
118  std::string new_name(name.begin(), name.end()-4);
119  new_name += pid_suffix.str();
120  std::remove(new_name.c_str());
121  }
122  if (name.size() - name.rfind(".xz") == 3)
123  {
124  std::string new_name(name.begin(), name.end()-3);
125  new_name += pid_suffix.str();
126  std::remove(new_name.c_str());
127  }
128 }
129 }
130 
131 namespace libMesh
132 {
133 
134 //-------------------------------------------------------------
135 // Xdr class implementation
136 Xdr::Xdr (const std::string & name,
137  const XdrMODE m) :
138  mode(m),
139  file_name(name),
140 #ifdef LIBMESH_HAVE_XDR
141  fp(nullptr),
142 #endif
143  in(),
144  out(),
145  comm_len(xdr_MAX_STRING_LENGTH),
146  gzipped_file(false),
147  bzipped_file(false),
148  xzipped_file(false)
149 {
150  this->open(name);
151 }
152 
153 
154 
156 {
157  this->close();
158 }
159 
160 
161 
162 void Xdr::open (const std::string & name)
163 {
164  file_name = name;
165 
166  if (name == "")
167  return;
168 
169  switch (mode)
170  {
171  case ENCODE:
172  case DECODE:
173  {
174 #ifdef LIBMESH_HAVE_XDR
175 
176  fp = fopen(name.c_str(), (mode == ENCODE) ? "w" : "r");
177  if (!fp)
178  libmesh_file_error(name.c_str());
179  xdrs.reset(new XDR);
180  xdrstdio_create (xdrs.get(), fp, (mode == ENCODE) ? XDR_ENCODE : XDR_DECODE);
181 #else
182 
183  libmesh_error_msg("ERROR: Functionality is not available.\n" \
184  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
185  << "The XDR interface is not available in this installation");
186 
187 #endif
188  return;
189 
190  }
191 
192  case READ:
193  {
194  gzipped_file = (name.size() - name.rfind(".gz") == 3);
195  bzipped_file = (name.size() - name.rfind(".bz2") == 4);
196  xzipped_file = (name.size() - name.rfind(".xz") == 3);
197 
198  if (gzipped_file)
199  {
200 #ifdef LIBMESH_HAVE_GZSTREAM
201  igzstream * inf = new igzstream;
202  libmesh_assert(inf);
203  in.reset(inf);
204  inf->open(name.c_str(), std::ios::in);
205 #else
206  libmesh_error_msg("ERROR: need gzstream to handle .gz files!!!");
207 #endif
208  }
209  else
210  {
211  std::ifstream * inf = new std::ifstream;
212  libmesh_assert(inf);
213  in.reset(inf);
214 
215  std::string new_name = unzip_file(name);
216 
217  inf->open(new_name.c_str(), std::ios::in);
218  }
219 
220  libmesh_assert(in.get());
221 
222  if (!in->good())
223  libmesh_file_error(name);
224  return;
225  }
226 
227  case WRITE:
228  {
229  gzipped_file = (name.size() - name.rfind(".gz") == 3);
230  bzipped_file = (name.size() - name.rfind(".bz2") == 4);
231  xzipped_file = (name.size() - name.rfind(".xz") == 3);
232 
233  if (gzipped_file)
234  {
235 #ifdef LIBMESH_HAVE_GZSTREAM
236  ogzstream * outf = new ogzstream;
237  libmesh_assert(outf);
238  out.reset(outf);
239  outf->open(name.c_str(), std::ios::out);
240 #else
241  libmesh_error_msg("ERROR: need gzstream to handle .gz files!!!");
242 #endif
243  }
244  else
245  {
246  std::ofstream * outf = new std::ofstream;
247  libmesh_assert(outf);
248  out.reset(outf);
249 
250  std::string new_name = name;
251 
252  if (bzipped_file)
253  new_name.erase(new_name.end() - 4, new_name.end());
254 
255  if (xzipped_file)
256  new_name.erase(new_name.end() - 3, new_name.end());
257 
258  outf->open(new_name.c_str(), std::ios::out);
259  }
260 
261  libmesh_assert(out.get());
262  libmesh_assert (out->good());
263  return;
264  }
265 
266  default:
267  libmesh_error_msg("Invalid mode = " << mode);
268  }
269 }
270 
271 
272 
273 void Xdr::close ()
274 {
275  switch (mode)
276  {
277  case ENCODE:
278  case DECODE:
279  {
280 #ifdef LIBMESH_HAVE_XDR
281 
282  if (xdrs)
283  {
284  xdr_destroy (xdrs.get());
285  xdrs.reset();
286  }
287 
288  if (fp)
289  {
290  fflush(fp);
291  fclose(fp);
292  fp = nullptr;
293  }
294 #else
295 
296  libmesh_error_msg("ERROR: Functionality is not available.\n" \
297  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
298  << "The XDR interface is not available in this installation");
299 
300 #endif
301  file_name = "";
302  return;
303  }
304 
305  case READ:
306  {
307  if (in.get() != nullptr)
308  {
309  in.reset();
310 
311  if (bzipped_file || xzipped_file)
312  remove_unzipped_file(file_name);
313  }
314  file_name = "";
315  return;
316  }
317 
318  case WRITE:
319  {
320  if (out.get() != nullptr)
321  {
322  out.reset();
323 
324  if (bzipped_file)
325  bzip_file(std::string(file_name.begin(), file_name.end()-4));
326 
327  else if (xzipped_file)
328  xzip_file(std::string(file_name.begin(), file_name.end()-3));
329  }
330  file_name = "";
331  return;
332  }
333 
334  default:
335  libmesh_error_msg("Invalid mode = " << mode);
336  }
337 }
338 
339 
340 
341 bool Xdr::is_open() const
342 {
343  switch (mode)
344  {
345  case ENCODE:
346  case DECODE:
347  {
348 #ifdef LIBMESH_HAVE_XDR
349 
350  if (fp)
351  if (xdrs)
352  return true;
353 
354  return false;
355 
356 #else
357 
358  libmesh_error_msg("ERROR: Functionality is not available.\n" \
359  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
360  << "The XDR interface is not available in this installation");
361 
362  return false;
363 
364 #endif
365 
366  }
367 
368  case READ:
369  {
370  if (in.get() != nullptr)
371  return in->good();
372  return false;
373  }
374 
375  case WRITE:
376  {
377  if (out.get() != nullptr)
378  return out->good();
379  return false;
380  }
381 
382  default:
383  libmesh_error_msg("Invalid mode = " << mode);
384  }
385 
386  return false;
387 }
388 
389 
390 
392 {
393  switch (mode)
394  {
395  case ENCODE:
396  case DECODE:
397  {
398 #ifdef LIBMESH_HAVE_XDR
399  libmesh_assert(fp);
400 
401  // Are we already at eof?
402  if (feof(fp))
403  return true;
404 
405  // Or about to reach eof?
406  int next = fgetc(fp);
407  if (next == EOF)
408  {
409  // We should *only* be at EOF, not otherwise broken
410  libmesh_assert(feof(fp));
411  libmesh_assert(!ferror(fp));
412 
413  // Reset the EOF indicator
414  clearerr(fp);
415  libmesh_assert(!ferror(fp));
416 
417  // We saw EOF
418  return true;
419  }
420 
421  // We didn't see EOF; restore whatever we did see.
422  ungetc(next, fp);
423  break;
424 #else
425 
426  libmesh_error_msg("ERROR: Functionality is not available.\n" \
427  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
428  << "The XDR interface is not available in this installation");
429 
430  return false;
431 
432 #endif
433 
434  }
435  case READ:
436  {
437  libmesh_assert(in.get());
438 
439  // Are we already at eof?
440  if (in->eof())
441  return true;
442 
443  // Or about to reach eof?
444  int next = in->peek();
445  if (next == EOF)
446  {
447  // We should *only* be at EOF, not otherwise broken
448  libmesh_assert(in->eof());
449  libmesh_assert(!in->fail());
450 
451  // Reset the EOF indicator
452  in->clear();
453  libmesh_assert(in->good());
454 
455  // We saw EOF
456  return true;
457  }
458  break;
459  }
460  default:
461  libmesh_error();
462  }
463 
464  return false;
465 }
466 
467 
468 
469 #ifdef LIBMESH_HAVE_XDR
470 
471 // Anonymous namespace for Xdr::data helper functions
472 namespace
473 {
474 
475 template <typename T>
476 xdrproc_t xdr_translator();
477 
478 template <typename T>
479 bool xdr_translate(XDR * x, T & a)
480 {
481  return (xdr_translator<T>())(x, &a, 0);
482 }
483 
484 template <>
485 bool xdr_translate(XDR * x,
486  std::string & s)
487 {
488  char sptr[xdr_MAX_STRING_LENGTH+1];
489  std::copy(s.begin(), s.end(), sptr);
490  sptr[s.size()] = 0;
491  unsigned int length = xdr_MAX_STRING_LENGTH;
492 
493  // Get a pointer to the beginning of the buffer. We need to pass
494  // its address to the xdr API.
495  char * begin = sptr;
496  bool b = xdr_string(x, &begin, length);
497 
498  // This is necessary when reading, but inefficient when writing...
499  length = cast_int<unsigned int>(std::strlen(sptr));
500  s.resize(length);
501  std::copy(sptr, sptr+length, s.begin());
502 
503  return b;
504 }
505 
506 template <typename T>
507 bool xdr_translate(XDR * x, std::complex<T> & a)
508 {
509  T r = a.real(), i = a.imag();
510  bool b1 = xdr_translate(x, r);
511  bool b2 = xdr_translate(x, i);
512  a = std::complex<T>(r,i);
513  return (b1 && b2);
514 }
515 
516 template <typename T>
517 bool xdr_translate(XDR * x, std::vector<T> & a)
518 {
519  unsigned int length = cast_int<unsigned int>(a.size());
520  xdr_u_int(x, &length);
521  if (length > 0)
522  {
523  a.resize(length);
524  return xdr_vector(x, reinterpret_cast<char *>(a.data()), length, sizeof(T),
525  xdr_translator<T>());
526  }
527  else
528  return true;
529 }
530 
531 template <typename T>
532 bool xdr_translate(XDR * x, std::vector<std::complex<T>> & a)
533 {
534  unsigned int length = cast_int<unsigned int>(a.size());
535  bool b = xdr_u_int(x, &length);
536  a.resize(length);
537  for (auto & val : a)
538  if (!xdr_translate(x, val))
539  b = false;
540  return b;
541 }
542 
543 template <>
544 bool xdr_translate(XDR * x, std::vector<std::string> & s)
545 {
546  unsigned int length = cast_int<unsigned int>(s.size());
547  bool b = xdr_u_int(x, &length);
548  s.resize(length);
549  for (auto & val : s)
550  if (!xdr_translate(x, val))
551  b = false;
552  return b;
553 }
554 
555 template <>
556 xdrproc_t xdr_translator<int>()
557 {
558  // Don't let XDR truncate anything on systems where int is 64-bit;
559  // xdr_int is hard-coded to write 32 bits.
560  if (sizeof(int) <= 4)
561  return (xdrproc_t)(xdr_int);
562  else if (sizeof(int) == sizeof(long long))
563  return (xdrproc_t)(xdr_longlong_t);
564  else if (sizeof(int) == sizeof(long))
565  return (xdrproc_t)(xdr_long);
566  else
567  libmesh_error();
568 }
569 
570 template <>
571 xdrproc_t xdr_translator<unsigned int>()
572 {
573  // Don't let XDR truncate anything on systems where int is 64-bit;
574  // xdr_u_int is hard-coded to write 32 bits.
575  if (sizeof(unsigned int) <= 4)
576  return (xdrproc_t)(xdr_u_int);
577  else if (sizeof(unsigned int) == sizeof(unsigned long))
578  return (xdrproc_t)(xdr_u_long);
579  else if (sizeof(unsigned int) == sizeof(unsigned long long))
580  return (xdrproc_t)(xdr_u_longlong_t);
581  else
582  libmesh_error();
583 }
584 
585 template <>
586 xdrproc_t xdr_translator<long int>()
587 {
588  // Don't let XDR truncate anything on systems where long is 64-bit;
589  // xdr_long is hard-coded to write 32 bits.
590  if (sizeof(long int) <= 4)
591  return (xdrproc_t)(xdr_long);
592  else if (sizeof(long int) == sizeof(long long))
593  return (xdrproc_t)(xdr_longlong_t);
594  else
595  libmesh_error();
596 }
597 
598 template <>
599 xdrproc_t xdr_translator<unsigned long int>()
600 {
601  // Don't let XDR truncate anything on systems where long is 64-bit;
602  // xdr_u_long is hard-coded to write 32 bits. This bit us HARD.
603  if (sizeof(unsigned long int) <= 4)
604  return (xdrproc_t)(xdr_u_long);
605  else if (sizeof(unsigned long int) == sizeof(unsigned long long))
606  return (xdrproc_t)(xdr_u_longlong_t);
607  else
608  libmesh_error();
609 }
610 
611 // All the other XDR routines should be safe, unless
612 // 1. You're on a system with sizeof(short)==8 and you want to store
613 // n>2^32 in a short; this will never happen since we assume
614 // sizeof(short) may be as small as 2 bytes and we use at least int
615 // for anything larger.
616 // 2. You're on a system with sizeof(long long) > 8, and you want to
617 // store n>2^64 in one. Welcome, 22nd century programmers; sorry we
618 // couldn't accomodate you.
619 template <>
620 xdrproc_t xdr_translator<long long>() { return (xdrproc_t)(xdr_longlong_t); }
621 
622 template <>
623 xdrproc_t xdr_translator<unsigned long long>() { return (xdrproc_t)(xdr_u_longlong_t); }
624 
625 template <>
626 xdrproc_t xdr_translator<short int>() { return (xdrproc_t)(xdr_short); }
627 
628 template <>
629 xdrproc_t xdr_translator<unsigned short int>() { return (xdrproc_t)(xdr_u_short); }
630 
631 template <>
632 xdrproc_t xdr_translator<char>() { return (xdrproc_t)(xdr_char); }
633 
634 template <>
635 xdrproc_t xdr_translator<signed char>() { return (xdrproc_t)(xdr_char); }
636 
637 template <>
638 xdrproc_t xdr_translator<unsigned char>() { return (xdrproc_t)(xdr_u_char); }
639 
640 template <>
641 xdrproc_t xdr_translator<float>() { return (xdrproc_t)(xdr_float); }
642 
643 template <>
644 xdrproc_t xdr_translator<double>() { return (xdrproc_t)(xdr_double); }
645 
646 // FIXME - no XDR love for long doubles?
647 template <>
648 xdrproc_t xdr_translator<long double>() { return (xdrproc_t)(xdr_double); }
649 
650 } // end anonymous namespace
651 
652 #endif
653 
654 template <typename T>
655 void Xdr::do_read(T & a)
656 {
657  *in >> a;
658  in->getline(comm, comm_len);
659 }
660 
661 template <typename T>
662 void Xdr::do_read(std::complex<T> & a)
663 {
664  T r, i;
665  *in >> r >> i;
666  a = std::complex<T>(r,i);
667  in->getline(comm, comm_len);
668 }
669 
670 template <>
671 void Xdr::do_read(std::string & a)
672 {
673  in->getline(comm, comm_len);
674 
675  a = "";
676 
677  for (unsigned int c=0; c<std::strlen(comm); c++)
678  {
679  if (comm[c] == '\t')
680  break;
681  a.push_back(comm[c]);
682  }
683 }
684 
685 template <typename T>
686 void Xdr::do_read(std::vector<T> & a)
687 {
688  unsigned int length=0;
689  data(length, "# vector length");
690  a.resize(length);
691 
692  for (std::size_t i=0; i<a.size(); i++)
693  {
694  libmesh_assert(in.get());
695  libmesh_assert (in->good());
696  *in >> a[i];
697  }
698  in->getline(comm, comm_len);
699 }
700 
701 template <typename T>
702 void Xdr::do_read(std::vector<std::complex<T>> & a)
703 {
704  unsigned int length=0;
705  data(length, "# vector length x 2 (complex)");
706  a.resize(length);
707 
708  for (std::size_t i=0; i<a.size(); i++)
709  {
710  T r, im;
711  libmesh_assert(in.get());
712  libmesh_assert (in->good());
713  *in >> r >> im;
714  a[i] = std::complex<T>(r,im);
715  }
716  in->getline(comm, comm_len);
717 }
718 
719 template <typename T>
720 void Xdr::do_write(T & a) { *out << a; }
721 
722 template <typename T>
723 void Xdr::do_write(std::complex<T> & a)
724 {
725  *out << a.real() << "\t " << a.imag();
726 }
727 
728 template <typename T>
729 void Xdr::do_write(std::vector<T> & a)
730 {
731  std::size_t length = a.size();
732  data(length, "# vector length");
733 
734  for (std::size_t i=0; i<a.size(); i++)
735  {
736  libmesh_assert(out.get());
737  libmesh_assert (out->good());
738  this->do_write(a[i]);
739  *out << "\t ";
740  }
741 }
742 
743 template <typename T>
744 void Xdr::do_write(std::vector<std::complex<T>> & a)
745 {
746  std::size_t length=a.size();
747  data(length, "# vector length x 2 (complex)");
748 
749  for (std::size_t i=0; i<a.size(); i++)
750  {
751  libmesh_assert(out.get());
752  libmesh_assert (out->good());
753  this->do_write(a[i]);
754  *out << "\t ";
755  }
756 }
757 
758 
759 
760 template <typename T>
761 void Xdr::data (T & a, const char * comment_in)
762 {
763  switch (mode)
764  {
765  case ENCODE:
766  case DECODE:
767  {
768 #ifdef LIBMESH_HAVE_XDR
769 
770  libmesh_assert (is_open());
771 
772  xdr_translate(xdrs.get(), a);
773 
774 #else
775 
776  libmesh_error_msg("ERROR: Functionality is not available.\n" \
777  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
778  << "The XDR interface is not available in this installation");
779 
780 #endif
781  return;
782  }
783 
784  case READ:
785  {
786  libmesh_assert(in.get());
787  libmesh_assert (in->good());
788 
789  this->do_read(a);
790 
791  return;
792  }
793 
794  case WRITE:
795  {
796  libmesh_assert(out.get());
797  libmesh_assert (out->good());
798 
799  // We will use scientific notation with a precision of 16
800  // digits in the following output. The desired precision and
801  // format will automatically determine the width.
802  *out << std::scientific
803  << std::setprecision(16);
804 
805  this->do_write(a);
806 
807  // If there's a comment provided, write a tab character and
808  // then the comment.
809  if (std::string(comment_in) != "")
810  *out << "\t " << comment_in;
811 
812  // Go to the next line.
813  *out << '\n';
814 
815  return;
816  }
817 
818  default:
819  libmesh_error_msg("Invalid mode = " << mode);
820  }
821 }
822 
823 
824 template <typename T>
825 void Xdr::data_stream (T * val, const unsigned int len, const unsigned int line_break)
826 {
827  switch (mode)
828  {
829  case ENCODE:
830  {
831 #ifdef LIBMESH_HAVE_XDR
832 
833  libmesh_assert (this->is_open());
834 
835  unsigned int size_of_type = cast_int<unsigned int>(sizeof(T));
836 
837  xdr_vector(xdrs.get(),
838  (char *) val,
839  len,
840  size_of_type,
841  xdr_translator<T>());
842 #else
843  libmesh_error_msg("ERROR: Functionality is not available.\n" \
844  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
845  << "The XDR interface is not available in this installation");
846 
847 #endif
848  return;
849  }
850 
851  case DECODE:
852  {
853 #ifdef LIBMESH_HAVE_XDR
854 
855  libmesh_assert (this->is_open());
856 
857  unsigned int size_of_type = cast_int<unsigned int>(sizeof(T));
858 
859  if (len > 0)
860  xdr_vector(xdrs.get(),
861  (char *) val,
862  len,
863  size_of_type,
864  xdr_translator<T>());
865 #else
866  libmesh_error_msg("ERROR: Functionality is not available.\n" \
867  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
868  << "The XDR interface is not available in this installation");
869 
870 #endif
871  return;
872  }
873 
874  case READ:
875  {
876  libmesh_assert(in.get());
877  libmesh_assert (in->good());
878 
879  for (unsigned int i=0; i<len; i++)
880  {
881  libmesh_assert(in.get());
882  libmesh_assert (in->good());
883  *in >> val[i];
884  }
885 
886  return;
887  }
888 
889  case WRITE:
890  {
891  libmesh_assert(out.get());
892  libmesh_assert (out->good());
893 
894  // We will use scientific notation with a precision of 16
895  // digits in the following output. The desired precision and
896  // format will automatically determine the width.
897  *out << std::scientific
898  << std::setprecision(16);
899 
900  if (line_break == libMesh::invalid_uint)
901  for (unsigned int i=0; i<len; i++)
902  {
903  libmesh_assert(out.get());
904  libmesh_assert (out->good());
905  *out << val[i] << " ";
906  }
907  else
908  {
909  const unsigned imax = std::min(line_break, len);
910  unsigned int cnt=0;
911  while (cnt < len)
912  {
913  for (unsigned int i=0; i<imax; i++)
914  {
915  libmesh_assert(out.get());
916  libmesh_assert (out->good());
917  *out << val[cnt++];
918 
919  // Write a space unless this is the last character on the current line.
920  if (i+1 != imax)
921  *out << " ";
922  }
923  libmesh_assert(out.get());
924  libmesh_assert (out->good());
925  *out << '\n';
926  }
927  }
928 
929  return;
930  }
931 
932  default:
933  libmesh_error_msg("Invalid mode = " << mode);
934  }
935 }
936 
937 
938 
939 template <>
940 void Xdr::data_stream (double * val, const unsigned int len, const unsigned int line_break)
941 {
942  switch (mode)
943  {
944  case ENCODE:
945  case DECODE:
946  {
947 #ifdef LIBMESH_HAVE_XDR
948 
949  libmesh_assert (this->is_open());
950 
951  if (len > 0)
952  xdr_vector(xdrs.get(),
953  (char *) val,
954  len,
955  sizeof(double),
956  (xdrproc_t) xdr_double);
957 
958 #else
959 
960  libmesh_error_msg("ERROR: Functionality is not available.\n" \
961  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
962  << "The XDR interface is not available in this installation");
963 
964 #endif
965  return;
966  }
967 
968  case READ:
969  {
970  libmesh_assert(in.get());
971  libmesh_assert (in->good());
972 
973  for (unsigned int i=0; i<len; i++)
974  {
975  libmesh_assert(in.get());
976  libmesh_assert (in->good());
977  *in >> val[i];
978  }
979 
980  return;
981  }
982 
983  case WRITE:
984  {
985  libmesh_assert(out.get());
986  libmesh_assert (out->good());
987 
988  // Save stream flags
989  std::ios_base::fmtflags out_flags = out->flags();
990 
991  // We will use scientific notation with a precision of 16
992  // digits in the following output. The desired precision and
993  // format will automatically determine the width.
994  *out << std::scientific
995  << std::setprecision(16);
996 
997  if (line_break == libMesh::invalid_uint)
998  for (unsigned int i=0; i<len; i++)
999  {
1000  libmesh_assert(out.get());
1001  libmesh_assert (out->good());
1002  *out << val[i] << ' ';
1003  }
1004  else
1005  {
1006  const unsigned imax = std::min(line_break, len);
1007  unsigned int cnt=0;
1008  while (cnt < len)
1009  {
1010  for (unsigned int i=0; i<imax; i++)
1011  {
1012  libmesh_assert(out.get());
1013  libmesh_assert (out->good());
1014  *out << val[cnt++];
1015 
1016  // Write a space unless this is the last character on the current line.
1017  if (i+1 != imax)
1018  *out << " ";
1019  }
1020  libmesh_assert(out.get());
1021  libmesh_assert (out->good());
1022  *out << '\n';
1023  }
1024  }
1025 
1026  // Restore stream flags
1027  out->flags(out_flags);
1028 
1029  return;
1030  }
1031 
1032  default:
1033  libmesh_error_msg("Invalid mode = " << mode);
1034  }
1035 }
1036 
1037 
1038 template <>
1039 void Xdr::data_stream (float * val, const unsigned int len, const unsigned int line_break)
1040 {
1041  switch (mode)
1042  {
1043  case ENCODE:
1044  case DECODE:
1045  {
1046 #ifdef LIBMESH_HAVE_XDR
1047 
1048  libmesh_assert (this->is_open());
1049 
1050  if (len > 0)
1051  xdr_vector(xdrs.get(),
1052  (char *) val,
1053  len,
1054  sizeof(float),
1055  (xdrproc_t) xdr_float);
1056 
1057 #else
1058 
1059  libmesh_error_msg("ERROR: Functionality is not available.\n" \
1060  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
1061  << "The XDR interface is not available in this installation");
1062 
1063 #endif
1064  return;
1065  }
1066 
1067  case READ:
1068  {
1069  libmesh_assert(in.get());
1070  libmesh_assert (in->good());
1071 
1072  for (unsigned int i=0; i<len; i++)
1073  {
1074  libmesh_assert(in.get());
1075  libmesh_assert (in->good());
1076  *in >> val[i];
1077  }
1078 
1079  return;
1080  }
1081 
1082  case WRITE:
1083  {
1084  libmesh_assert(out.get());
1085  libmesh_assert (out->good());
1086 
1087  // Save stream flags
1088  std::ios_base::fmtflags out_flags = out->flags();
1089 
1090  // We will use scientific notation with a precision of 16
1091  // digits in the following output. The desired precision and
1092  // format will automatically determine the width.
1093  *out << std::scientific
1094  << std::setprecision(16);
1095 
1096  if (line_break == libMesh::invalid_uint)
1097  for (unsigned int i=0; i<len; i++)
1098  {
1099  libmesh_assert(out.get());
1100  libmesh_assert (out->good());
1101  *out << val[i] << ' ';
1102  }
1103  else
1104  {
1105  const unsigned imax = std::min(line_break, len);
1106  unsigned int cnt=0;
1107  while (cnt < len)
1108  {
1109  for (unsigned int i=0; i<imax; i++)
1110  {
1111  libmesh_assert(out.get());
1112  libmesh_assert (out->good());
1113  *out << val[cnt++];
1114 
1115  // Write a space unless this is the last character on the current line.
1116  if (i+1 != imax)
1117  *out << " ";
1118  }
1119  libmesh_assert(out.get());
1120  libmesh_assert (out->good());
1121  *out << '\n';
1122  }
1123  }
1124 
1125  // Restore stream flags
1126  out->flags(out_flags);
1127 
1128  return;
1129  }
1130 
1131  default:
1132  libmesh_error_msg("Invalid mode = " << mode);
1133  }
1134 }
1135 template <>
1136 void Xdr::data_stream (long double * val, const unsigned int len, const unsigned int line_break)
1137 {
1138  switch (mode)
1139  {
1140  case ENCODE:
1141  case DECODE:
1142  {
1143 #ifdef LIBMESH_HAVE_XDR
1144 
1145  libmesh_assert (this->is_open());
1146 
1147  // FIXME[JWP]: How to implement this for long double? Mac OS
1148  // X defines 'xdr_quadruple' but AFAICT, it does not exist for
1149  // Linux... for now, reading/writing XDR files with long
1150  // doubles drops back to double precision, but you can still
1151  // write long double ASCII files of course.
1152  // if (len > 0)
1153  // xdr_vector(xdrs.get(),
1154  // (char *) val,
1155  // len,
1156  // sizeof(double),
1157  // (xdrproc_t) xdr_quadruple);
1158 
1159  if (len > 0)
1160  {
1161  std::vector<double> io_buffer (len);
1162 
1163  // Fill io_buffer if we are writing.
1164  if (mode == ENCODE)
1165  for (unsigned int i=0, cnt=0; i<len; i++)
1166  io_buffer[cnt++] = double(val[i]);
1167 
1168  xdr_vector(xdrs.get(),
1169  reinterpret_cast<char *>(io_buffer.data()),
1170  len,
1171  sizeof(double),
1172  (xdrproc_t) xdr_double);
1173 
1174  // Fill val array if we are reading.
1175  if (mode == DECODE)
1176  for (unsigned int i=0, cnt=0; i<len; i++)
1177  {
1178  val[i] = io_buffer[cnt++];
1179  }
1180  }
1181 
1182 #else
1183 
1184  libmesh_error_msg("ERROR: Functionality is not available.\n" \
1185  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
1186  << "The XDR interface is not available in this installation");
1187 
1188 #endif
1189  return;
1190  }
1191 
1192  case READ:
1193  {
1194  libmesh_assert(in.get());
1195  libmesh_assert (in->good());
1196 
1197  for (unsigned int i=0; i<len; i++)
1198  {
1199  libmesh_assert(in.get());
1200  libmesh_assert (in->good());
1201  *in >> val[i];
1202  }
1203 
1204  return;
1205  }
1206 
1207  case WRITE:
1208  {
1209  libmesh_assert(out.get());
1210  libmesh_assert (out->good());
1211 
1212  // Save stream flags
1213  std::ios_base::fmtflags out_flags = out->flags();
1214 
1215  // We will use scientific notation with a precision of 16
1216  // digits in the following output. The desired precision and
1217  // format will automatically determine the width.
1218  *out << std::scientific
1219  << std::setprecision(16);
1220 
1221  if (line_break == libMesh::invalid_uint)
1222  for (unsigned int i=0; i<len; i++)
1223  {
1224  libmesh_assert(out.get());
1225  libmesh_assert (out->good());
1226  *out << val[i] << ' ';
1227  }
1228  else
1229  {
1230  const unsigned imax = std::min(line_break, len);
1231  unsigned int cnt=0;
1232  while (cnt < len)
1233  {
1234  for (unsigned int i=0; i<imax; i++)
1235  {
1236  libmesh_assert(out.get());
1237  libmesh_assert (out->good());
1238  *out << val[cnt++];
1239 
1240  // Write a space unless this is the last character on the current line.
1241  if (i+1 != imax)
1242  *out << " ";
1243  }
1244  libmesh_assert(out.get());
1245  libmesh_assert (out->good());
1246  *out << '\n';
1247  }
1248  }
1249 
1250  // Restore stream flags
1251  out->flags(out_flags);
1252 
1253  return;
1254  }
1255 
1256  default:
1257  libmesh_error_msg("Invalid mode = " << mode);
1258  }
1259 }
1260 
1261 
1262 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
1263 template <>
1264 void Xdr::data_stream (std::complex<double> * val, const unsigned int len, const unsigned int line_break)
1265 {
1266  switch (mode)
1267  {
1268  case ENCODE:
1269  case DECODE:
1270  {
1271 #ifdef LIBMESH_HAVE_XDR
1272 
1273  libmesh_assert (this->is_open());
1274 
1275 
1276  if (len > 0)
1277  {
1278  std::vector<double> io_buffer (2*len);
1279 
1280  // Fill io_buffer if we are writing.
1281  if (mode == ENCODE)
1282  for (unsigned int i=0, cnt=0; i<len; i++)
1283  {
1284  io_buffer[cnt++] = val[i].real();
1285  io_buffer[cnt++] = val[i].imag();
1286  }
1287 
1288  xdr_vector(xdrs.get(),
1289  reinterpret_cast<char *>(io_buffer.data()),
1290  2*len,
1291  sizeof(double),
1292  (xdrproc_t) xdr_double);
1293 
1294  // Fill val array if we are reading.
1295  if (mode == DECODE)
1296  for (unsigned int i=0, cnt=0; i<len; i++)
1297  {
1298  double re = io_buffer[cnt++];
1299  double im = io_buffer[cnt++];
1300  val[i] = std::complex<double>(re,im);
1301  }
1302  }
1303 #else
1304 
1305  libmesh_error_msg("ERROR: Functionality is not available.\n" \
1306  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
1307  << "The XDR interface is not available in this installation");
1308 
1309 #endif
1310  return;
1311  }
1312 
1313  case READ:
1314  {
1315  libmesh_assert(in.get());
1316  libmesh_assert (in->good());
1317 
1318  for (unsigned int i=0; i<len; i++)
1319  {
1320  libmesh_assert(in.get());
1321  libmesh_assert (in->good());
1322  double re, im;
1323  *in >> re >> im;
1324  val[i] = std::complex<double>(re,im);
1325  }
1326 
1327  return;
1328  }
1329 
1330  case WRITE:
1331  {
1332  libmesh_assert(out.get());
1333  libmesh_assert (out->good());
1334 
1335  // Save stream flags
1336  std::ios_base::fmtflags out_flags = out->flags();
1337 
1338  // We will use scientific notation with a precision of 16
1339  // digits in the following output. The desired precision and
1340  // format will automatically determine the width.
1341  *out << std::scientific
1342  << std::setprecision(16);
1343 
1344  if (line_break == libMesh::invalid_uint)
1345  for (unsigned int i=0; i<len; i++)
1346  {
1347  libmesh_assert(out.get());
1348  libmesh_assert (out->good());
1349  *out << val[i].real() << ' ';
1350  *out << val[i].imag() << ' ';
1351  }
1352  else
1353  {
1354  const unsigned imax = std::min(line_break, len);
1355  unsigned int cnt=0;
1356  while (cnt < len)
1357  {
1358  for (unsigned int i=0; i<imax; i++)
1359  {
1360  libmesh_assert(out.get());
1361  libmesh_assert (out->good());
1362  *out << val[cnt].real() << ' ';
1363  *out << val[cnt].imag();
1364  cnt++;
1365 
1366  // Write a space unless this is the last character on the current line.
1367  if (i+1 != imax)
1368  *out << " ";
1369  }
1370  libmesh_assert(out.get());
1371  libmesh_assert (out->good());
1372  *out << '\n';
1373  }
1374  }
1375 
1376  // Restore stream flags
1377  out->flags(out_flags);
1378 
1379  return;
1380  }
1381 
1382  default:
1383  libmesh_error_msg("Invalid mode = " << mode);
1384  }
1385 }
1386 
1387 template <>
1388 void Xdr::data_stream (std::complex<long double> * val, const unsigned int len, const unsigned int line_break)
1389 {
1390  switch (mode)
1391  {
1392  case ENCODE:
1393  case DECODE:
1394  {
1395 #ifdef LIBMESH_HAVE_XDR
1396 
1397  libmesh_assert (this->is_open());
1398 
1399  // FIXME[JWP]: How to implement this for long double? Mac OS
1400  // X defines 'xdr_quadruple' but AFAICT, it does not exist for
1401  // Linux... for now, reading/writing XDR files with long
1402  // doubles drops back to double precision, but you can still
1403  // write long double ASCII files of course.
1404 
1405  if (len > 0)
1406  {
1407  std::vector<double> io_buffer (2*len);
1408 
1409  // Fill io_buffer if we are writing.
1410  if (mode == ENCODE)
1411  for (unsigned int i=0, cnt=0; i<len; i++)
1412  {
1413  io_buffer[cnt++] = val[i].real();
1414  io_buffer[cnt++] = val[i].imag();
1415  }
1416 
1417  xdr_vector(xdrs.get(),
1418  reinterpret_cast<char *>(io_buffer.data()),
1419  2*len,
1420  sizeof(double),
1421  (xdrproc_t) xdr_double);
1422 
1423  // Fill val array if we are reading.
1424  if (mode == DECODE)
1425  for (unsigned int i=0, cnt=0; i<len; i++)
1426  {
1427  double re = io_buffer[cnt++];
1428  double im = io_buffer[cnt++];
1429  val[i] = std::complex<long double>(re, im);
1430  }
1431  }
1432 #else
1433 
1434  libmesh_error_msg("ERROR: Functionality is not available.\n" \
1435  << "Make sure LIBMESH_HAVE_XDR is defined at build time\n" \
1436  << "The XDR interface is not available in this installation");
1437 
1438 #endif
1439  return;
1440  }
1441 
1442  case READ:
1443  {
1444  libmesh_assert(in.get());
1445  libmesh_assert (in->good());
1446 
1447  for (unsigned int i=0; i<len; i++)
1448  {
1449  libmesh_assert(in.get());
1450  libmesh_assert (in->good());
1451  long double re, im;
1452  *in >> re >> im;
1453  val[i] = std::complex<long double>(re,im);
1454  }
1455 
1456  return;
1457  }
1458 
1459  case WRITE:
1460  {
1461  libmesh_assert(out.get());
1462  libmesh_assert (out->good());
1463 
1464 
1465  // Save stream flags
1466  std::ios_base::fmtflags out_flags = out->flags();
1467 
1468  // We will use scientific notation with a precision of
1469  // 'digits10' digits in the following output. The desired
1470  // precision and format will automatically determine the
1471  // width. Note: digit10 is the number of digits (in decimal
1472  // base) that can be represented without change. Equivalent
1473  // to FLT_DIG, DBL_DIG or LDBL_DIG for floating types.
1474  *out << std::scientific
1475  << std::setprecision(std::numeric_limits<long double>::digits10);
1476 
1477  if (line_break == libMesh::invalid_uint)
1478  for (unsigned int i=0; i<len; i++)
1479  {
1480  libmesh_assert(out.get());
1481  libmesh_assert (out->good());
1482  *out << val[i].real() << ' ' << val[i].imag() << ' ';
1483  }
1484  else
1485  {
1486  const unsigned imax = std::min(line_break, len);
1487  unsigned int cnt=0;
1488  while (cnt < len)
1489  {
1490  for (unsigned int i=0; i<imax; i++)
1491  {
1492  libmesh_assert(out.get());
1493  libmesh_assert (out->good());
1494  *out << val[cnt].real() << ' ' << val[cnt].imag();
1495  cnt++;
1496 
1497  // Write a space unless this is the last character on the current line.
1498  if (i+1 != imax)
1499  *out << " ";
1500  }
1501  libmesh_assert(out.get());
1502  libmesh_assert (out->good());
1503  *out << '\n';
1504  }
1505  }
1506 
1507  // Restore stream flags
1508  out->flags(out_flags);
1509 
1510  return;
1511  }
1512 
1513  default:
1514  libmesh_error_msg("Invalid mode = " << mode);
1515  }
1516 }
1517 #endif // # LIBMESH_USE_COMPLEX_NUMBERS
1518 
1519 void Xdr::comment (std::string & comment_in)
1520 {
1521  switch (mode)
1522  {
1523  case ENCODE:
1524  case DECODE:
1525  {
1526  return;
1527  }
1528 
1529  case READ:
1530  {
1531  libmesh_assert(in.get());
1532  libmesh_assert (in->good());
1533  in->getline(comm, comm_len);
1534  return;
1535  }
1536 
1537  case WRITE:
1538  {
1539  libmesh_assert(out.get());
1540  libmesh_assert (out->good());
1541  *out << "\t " << comment_in << '\n';
1542  return;
1543  }
1544 
1545  default:
1546  libmesh_error_msg("Invalid mode = " << mode);
1547  }
1548 }
1549 
1550 
1551 #undef xdr_REAL
1552 
1553 
1554 //
1555 template void Xdr::data<int> (int &, const char *);
1556 template void Xdr::data<unsigned int> (unsigned int &, const char *);
1557 template void Xdr::data<unsigned short int> (unsigned short int &, const char *);
1558 template void Xdr::data<short int> (short int &, const char *);
1559 template void Xdr::data<unsigned long int> (unsigned long int &, const char *);
1560 template void Xdr::data<unsigned long long> (unsigned long long &, const char *);
1561 template void Xdr::data<long int> (long int &, const char *);
1562 template void Xdr::data<long long> (long long &, const char *);
1563 template void Xdr::data<char> (char &, const char *);
1564 template void Xdr::data<signed char> (signed char &, const char *);
1565 template void Xdr::data<unsigned char> (unsigned char &, const char *);
1566 template void Xdr::data<float> (float &, const char *);
1567 template void Xdr::data<double> (double &, const char *);
1568 template void Xdr::data<long double> (long double &, const char *);
1569 template void Xdr::data<std::complex<float>> (std::complex<float> &, const char *);
1570 template void Xdr::data<std::complex<double>> (std::complex<double> &, const char *);
1571 template void Xdr::data<std::complex<long double>> (std::complex<long double> &, const char *);
1572 template void Xdr::data<std::string> (std::string &, const char *);
1573 template void Xdr::data<std::vector<int>> (std::vector<int> &, const char *);
1574 template void Xdr::data<std::vector<unsigned int>> (std::vector<unsigned int> &, const char *);
1575 template void Xdr::data<std::vector<short int>> (std::vector<short int> &, const char *);
1576 template void Xdr::data<std::vector<unsigned short int>> (std::vector<unsigned short int> &, const char *);
1577 template void Xdr::data<std::vector<long int>> (std::vector<long int> &, const char *);
1578 template void Xdr::data<std::vector<long long>> (std::vector<long long> &, const char *);
1579 template void Xdr::data<std::vector<unsigned long int>> (std::vector<unsigned long int> &, const char *);
1580 template void Xdr::data<std::vector<unsigned long long>> (std::vector<unsigned long long> &, const char *);
1581 template void Xdr::data<std::vector<char>> (std::vector<char> &, const char *);
1582 template void Xdr::data<std::vector<signed char>> (std::vector<signed char> &, const char *);
1583 template void Xdr::data<std::vector<unsigned char>> (std::vector<unsigned char> &, const char *);
1584 template void Xdr::data<std::vector<float>> (std::vector<float> &, const char *);
1585 template void Xdr::data<std::vector<double>> (std::vector<double> &, const char *);
1586 template void Xdr::data<std::vector<long double>> (std::vector<long double> &, const char *);
1587 template void Xdr::data<std::vector<std::complex<float>>> (std::vector<std::complex<float>> &, const char *);
1588 template void Xdr::data<std::vector<std::complex<double>>> (std::vector<std::complex<double>> &, const char *);
1589 template void Xdr::data<std::vector<std::complex<long double>>> (std::vector<std::complex<long double>> &, const char *);
1590 template void Xdr::data<std::vector<std::string>> (std::vector<std::string> &, const char *);
1591 template void Xdr::data_stream<unsigned char> (unsigned char * val, const unsigned int len, const unsigned int line_break);
1592 template void Xdr::data_stream<short int> (short int * val, const unsigned int len, const unsigned int line_break);
1593 template void Xdr::data_stream<int> (int * val, const unsigned int len, const unsigned int line_break);
1594 template void Xdr::data_stream<long long> (long long * val, const unsigned int len, const unsigned int line_break);
1595 template void Xdr::data_stream<unsigned short int> (unsigned short int * val, const unsigned int len, const unsigned int line_break);
1596 template void Xdr::data_stream<unsigned int> (unsigned int * val, const unsigned int len, const unsigned int line_break);
1597 template void Xdr::data_stream<unsigned long int> (unsigned long int * val, const unsigned int len, const unsigned int line_break);
1598 template void Xdr::data_stream<unsigned long long> (unsigned long long * val, const unsigned int len, const unsigned int line_break);
1599 
1600 } // namespace libMesh
std::string name(const ElemQuality q)
Definition: elem_quality.C:42
FILE * fp
Definition: xdr_cxx.h:219
const int comm_len
Definition: xdr_cxx.h:236
void data(T &a, const char *comment="")
Definition: xdr_cxx.C:761
std::string file_name
Definition: xdr_cxx.h:206
const unsigned int xdr_MAX_STRING_LENGTH
Definition: xdr_cxx.h:44
void do_write(T &a)
Definition: xdr_cxx.C:720
const unsigned int invalid_uint
Definition: libmesh.h:245
char comm[xdr_MAX_STRING_LENGTH]
Definition: xdr_cxx.h:237
void comment(std::string &)
Definition: xdr_cxx.C:1519
void close()
Definition: xdr_cxx.C:273
bool xzipped_file
Definition: xdr_cxx.h:242
bool bzipped_file
Definition: xdr_cxx.h:242
const XdrMODE mode
Definition: xdr_cxx.h:201
void do_read(T &a)
Definition: xdr_cxx.C:655
bool gzipped_file
Definition: xdr_cxx.h:242
std::unique_ptr< std::istream > in
Definition: xdr_cxx.h:226
std::unique_ptr< std::ostream > out
Definition: xdr_cxx.h:231
bool is_eof()
Definition: xdr_cxx.C:391
std::unique_ptr< XDR > xdrs
Definition: xdr_cxx.h:214
static const unsigned int next[3]
bool is_open() const
Definition: xdr_cxx.C:341
void open(const std::string &name)
Definition: xdr_cxx.C:162
Xdr(const std::string &name="", const XdrMODE m=UNKNOWN)
Definition: xdr_cxx.C:136
void data_stream(T *val, const unsigned int len, const unsigned int line_break=libMesh::invalid_uint)
Definition: xdr_cxx.C:825
OStreamProxy out(std::cout)
long double min(long double a, double b)