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

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo