xdr_cxx.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 // C/C++ includes 00020 #include <cstring> 00021 #include <limits> 00022 #include <iomanip> 00023 #include <sstream> 00024 00025 // Local includes 00026 #include "libmesh/xdr_cxx.h" 00027 #include "libmesh/libmesh_logging.h" 00028 #ifdef LIBMESH_HAVE_GZSTREAM 00029 # include "gzstream.h" 00030 #endif 00031 00032 00033 // Anonymous namespace for implementation details. 00034 namespace { 00035 00036 // Nasty hacks for reading/writing zipped files 00037 void bzip_file (const std::string &unzipped_name) 00038 { 00039 // There's no parallel bzip2 for us to call, but we might 00040 // be running multiple zip utilities on parallel files. 00041 // libmesh_assert_equal_to (libMesh::processor_id(), 0); 00042 00043 #ifdef LIBMESH_HAVE_BZIP 00044 START_LOG("system(bzip2)", "XdrIO"); 00045 00046 std::string system_string = "bzip2 -f "; 00047 system_string += unzipped_name; 00048 if (std::system(system_string.c_str())) 00049 libmesh_file_error(system_string); 00050 00051 STOP_LOG("system(bzip2)", "XdrIO"); 00052 #else 00053 libMesh::err << "ERROR: need bzip2/bunzip2 to create " 00054 << unzipped_name << ".bz2" 00055 << std::endl; 00056 libmesh_error(); 00057 #endif 00058 } 00059 00060 std::string unzip_file (const std::string &name) 00061 { 00062 // There's no parallel bunzip2 or xz for us to call, but we might 00063 // be running multiple zip utilities on parallel files. 00064 // libmesh_assert_equal_to (libMesh::processor_id(), 0); 00065 00066 std::ostringstream pid_suffix; 00067 pid_suffix << '_' << getpid(); 00068 00069 std::string new_name = name; 00070 if (name.size() - name.rfind(".bz2") == 4) 00071 { 00072 #ifdef LIBMESH_HAVE_BZIP 00073 new_name.erase(new_name.end() - 4, new_name.end()); 00074 new_name += pid_suffix.str(); 00075 START_LOG("system(bunzip2)", "XdrIO"); 00076 std::string system_string = "bunzip2 -f -k -c "; 00077 system_string += name + " > " + new_name; 00078 if (std::system(system_string.c_str())) 00079 libmesh_file_error(system_string); 00080 STOP_LOG("system(bunzip2)", "XdrIO"); 00081 #else 00082 libMesh::err << "ERROR: need bzip2/bunzip2 to open .bz2 file " 00083 << name << std::endl; 00084 libmesh_error(); 00085 #endif 00086 } 00087 else if (name.size() - name.rfind(".xz") == 3) 00088 { 00089 #ifdef LIBMESH_HAVE_XZ 00090 new_name.erase(new_name.end() - 3, new_name.end()); 00091 new_name += pid_suffix.str(); 00092 START_LOG("system(xz -d)", "XdrIO"); 00093 std::string system_string = "xz -f -d -k -c "; 00094 system_string += name + " > " + new_name; 00095 if (std::system(system_string.c_str())) 00096 libmesh_file_error(system_string); 00097 STOP_LOG("system(xz -d)", "XdrIO"); 00098 #else 00099 libMesh::err << "ERROR: need xz to open .xz file " 00100 << name << std::endl; 00101 libmesh_error(); 00102 #endif 00103 } 00104 return new_name; 00105 } 00106 00107 void xzip_file (const std::string &unzipped_name) 00108 { 00109 // There's no parallel xz for us to call, but we might 00110 // be running multiple zip utilities on parallel files. 00111 // libmesh_assert_equal_to (libMesh::processor_id(), 0); 00112 00113 #ifdef LIBMESH_HAVE_XZ 00114 START_LOG("system(xz)", "XdrIO"); 00115 00116 std::string system_string = "xz -f "; 00117 system_string += unzipped_name; 00118 if (std::system(system_string.c_str())) 00119 libmesh_file_error(system_string); 00120 00121 STOP_LOG("system(xz)", "XdrIO"); 00122 #else 00123 libMesh::err << "ERROR: need xz to create " 00124 << unzipped_name << ".xz" 00125 << std::endl; 00126 libmesh_error(); 00127 #endif 00128 } 00129 00130 00131 // remove an unzipped file 00132 void remove_unzipped_file (const std::string &name) 00133 { 00134 std::ostringstream pid_suffix; 00135 pid_suffix << '_' << getpid(); 00136 00137 // If we temporarily decompressed a file, remove the 00138 // uncompressed version 00139 if (name.size() - name.rfind(".bz2") == 4) 00140 { 00141 std::string new_name(name.begin(), name.end()-4); 00142 new_name += pid_suffix.str(); 00143 std::remove(new_name.c_str()); 00144 } 00145 if (name.size() - name.rfind(".xz") == 3) 00146 { 00147 std::string new_name(name.begin(), name.end()-3); 00148 new_name += pid_suffix.str(); 00149 std::remove(new_name.c_str()); 00150 } 00151 } 00152 } 00153 00154 namespace libMesh 00155 { 00156 00157 //------------------------------------------------------------- 00158 // Xdr class implementation 00159 Xdr::Xdr (const std::string& name, const XdrMODE m) : 00160 mode(m), 00161 file_name(name), 00162 #ifdef LIBMESH_HAVE_XDR 00163 xdrs(NULL), 00164 fp(NULL), 00165 #endif 00166 in(NULL), 00167 out(NULL), 00168 comm_len(xdr_MAX_STRING_LENGTH), 00169 gzipped_file(false), 00170 bzipped_file(false), 00171 xzipped_file(false) 00172 { 00173 this->open(name); 00174 } 00175 00176 00177 00178 Xdr::~Xdr() 00179 { 00180 this->close(); 00181 } 00182 00183 00184 00185 void Xdr::open (const std::string& name) 00186 { 00187 file_name = name; 00188 00189 if (name == "") 00190 return; 00191 00192 switch (mode) 00193 { 00194 case ENCODE: 00195 case DECODE: 00196 { 00197 #ifdef LIBMESH_HAVE_XDR 00198 00199 fp = fopen(name.c_str(), (mode == ENCODE) ? "w" : "r"); 00200 if (!fp) 00201 libmesh_file_error(name.c_str()); 00202 xdrs = new XDR; 00203 xdrstdio_create (xdrs, fp, (mode == ENCODE) ? XDR_ENCODE : XDR_DECODE); 00204 #else 00205 00206 libMesh::err << "ERROR: Functionality is not available." << std::endl 00207 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00208 << std::endl 00209 << "The XDR interface is not available in this installation" 00210 << std::endl; 00211 00212 libmesh_error(); 00213 00214 #endif 00215 return; 00216 00217 } 00218 00219 case READ: 00220 { 00221 gzipped_file = (name.size() - name.rfind(".gz") == 3); 00222 bzipped_file = (name.size() - name.rfind(".bz2") == 4); 00223 xzipped_file = (name.size() - name.rfind(".xz") == 3); 00224 00225 if (gzipped_file) 00226 { 00227 #ifdef LIBMESH_HAVE_GZSTREAM 00228 igzstream *inf = new igzstream; 00229 libmesh_assert(inf); 00230 in.reset(inf); 00231 inf->open(name.c_str(), std::ios::in); 00232 #else 00233 libMesh::err << "ERROR: need gzstream to handle .gz files!!!" 00234 << std::endl; 00235 libmesh_error(); 00236 #endif 00237 } 00238 else 00239 { 00240 std::ifstream *inf = new std::ifstream; 00241 libmesh_assert(inf); 00242 in.reset(inf); 00243 00244 std::string new_name = unzip_file(name); 00245 00246 inf->open(new_name.c_str(), std::ios::in); 00247 } 00248 00249 libmesh_assert(in.get()); 00250 libmesh_assert (in->good()); 00251 return; 00252 } 00253 00254 case WRITE: 00255 { 00256 gzipped_file = (name.size() - name.rfind(".gz") == 3); 00257 bzipped_file = (name.size() - name.rfind(".bz2") == 4); 00258 xzipped_file = (name.size() - name.rfind(".xz") == 3); 00259 00260 if (gzipped_file) 00261 { 00262 #ifdef LIBMESH_HAVE_GZSTREAM 00263 ogzstream *outf = new ogzstream; 00264 libmesh_assert(outf); 00265 out.reset(outf); 00266 outf->open(name.c_str(), std::ios::out); 00267 #else 00268 libMesh::err << "ERROR: need gzstream to handle .gz files!!!" 00269 << std::endl; 00270 libmesh_error(); 00271 #endif 00272 } 00273 else 00274 { 00275 std::ofstream *outf = new std::ofstream; 00276 libmesh_assert(outf); 00277 out.reset(outf); 00278 00279 std::string new_name = name; 00280 00281 if (bzipped_file) 00282 new_name.erase(new_name.end() - 4, new_name.end()); 00283 00284 if (xzipped_file) 00285 new_name.erase(new_name.end() - 3, new_name.end()); 00286 00287 outf->open(new_name.c_str(), std::ios::out); 00288 } 00289 00290 libmesh_assert(out.get()); 00291 libmesh_assert (out->good()); 00292 return; 00293 } 00294 00295 default: 00296 libmesh_error(); 00297 } 00298 } 00299 00300 00301 00302 void Xdr::close () 00303 { 00304 switch (mode) 00305 { 00306 case ENCODE: 00307 case DECODE: 00308 { 00309 #ifdef LIBMESH_HAVE_XDR 00310 00311 if (xdrs) 00312 { 00313 xdr_destroy (xdrs); 00314 delete xdrs; 00315 xdrs = NULL; 00316 } 00317 00318 if (fp) 00319 { 00320 fflush(fp); 00321 fclose(fp); 00322 fp = NULL; 00323 } 00324 #else 00325 00326 libMesh::err << "ERROR: Functionality is not available." << std::endl 00327 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00328 << std::endl 00329 << "The XDR interface is not available in this installation" 00330 << std::endl; 00331 00332 libmesh_error(); 00333 00334 #endif 00335 file_name = ""; 00336 return; 00337 } 00338 00339 case READ: 00340 { 00341 if (in.get() != NULL) 00342 { 00343 in.reset(); 00344 00345 if (bzipped_file || xzipped_file) 00346 remove_unzipped_file(file_name); 00347 } 00348 file_name = ""; 00349 return; 00350 } 00351 00352 case WRITE: 00353 { 00354 if (out.get() != NULL) 00355 { 00356 out.reset(); 00357 00358 if (bzipped_file) 00359 bzip_file(std::string(file_name.begin(), file_name.end()-4)); 00360 00361 else if (xzipped_file) 00362 xzip_file(std::string(file_name.begin(), file_name.end()-3)); 00363 } 00364 file_name = ""; 00365 return; 00366 } 00367 00368 default: 00369 libmesh_error(); 00370 } 00371 } 00372 00373 00374 00375 bool Xdr::is_open() const 00376 { 00377 switch (mode) 00378 { 00379 case ENCODE: 00380 case DECODE: 00381 { 00382 #ifdef LIBMESH_HAVE_XDR 00383 00384 if (fp) 00385 if (xdrs) 00386 return true; 00387 00388 return false; 00389 00390 #else 00391 00392 libMesh::err << "ERROR: Functionality is not available." << std::endl 00393 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00394 << std::endl 00395 << "The XDR interface is not available in this installation" 00396 << std::endl; 00397 00398 libmesh_error(); 00399 00400 return false; 00401 00402 #endif 00403 00404 } 00405 00406 case READ: 00407 { 00408 if (in.get() != NULL) 00409 return in->good(); 00410 return false; 00411 } 00412 00413 case WRITE: 00414 { 00415 if (out.get() != NULL) 00416 return out->good(); 00417 return false; 00418 } 00419 00420 default: 00421 libmesh_error(); 00422 } 00423 00424 return false; 00425 } 00426 00427 00428 #ifdef LIBMESH_HAVE_XDR 00429 00430 // Anonymous namespace for Xdr::data helper functions 00431 namespace 00432 { 00433 00434 template <typename T> 00435 xdrproc_t xdr_translator(); 00436 00437 template <typename T> 00438 bool xdr_translate(XDR* x, T& a) {return (xdr_translator<T>())(x, &a); } 00439 00440 template <> 00441 bool xdr_translate(XDR* x, std::string& s) { 00442 char* sptr = new char[xdr_MAX_STRING_LENGTH+1]; 00443 std::copy(s.begin(), s.end(), sptr); 00444 sptr[s.size()] = 0; 00445 std::size_t length = xdr_MAX_STRING_LENGTH; 00446 bool b = xdr_string(x, &sptr, length); 00447 00448 // This is necessary when reading, but inefficient when writing... 00449 length = std::strlen(sptr); 00450 s.resize(length); 00451 std::copy(sptr, sptr+length, s.begin()); 00452 00453 delete [] sptr; 00454 return b; 00455 } 00456 00457 template <typename T> 00458 bool xdr_translate(XDR* x, std::complex<T>& a) { 00459 T r = a.real(), i = a.imag(); 00460 bool b1 = xdr_translate(x, r); 00461 bool b2 = xdr_translate(x, i); 00462 a = std::complex<T>(r,i); 00463 return (b1 && b2); 00464 } 00465 00466 template <typename T> 00467 bool xdr_translate(XDR* x, std::vector<T>& a) { 00468 unsigned int length = libmesh_cast_int<unsigned int>(a.size()); 00469 xdr_u_int(x, &length); 00470 if (length > 0) 00471 { 00472 a.resize(length); 00473 return xdr_vector(x, (char*) &a[0], length, sizeof(T), 00474 xdr_translator<T>()); 00475 } 00476 else 00477 return true; 00478 } 00479 00480 template <typename T> 00481 bool xdr_translate(XDR* x, std::vector<std::complex<T> >& a) { 00482 unsigned int length = libmesh_cast_int<unsigned int>(a.size()); 00483 bool b = xdr_u_int(x, &length); 00484 a.resize(length); 00485 typename std::vector<std::complex<T> >::iterator iter = a.begin(); 00486 for (; iter != a.end(); ++iter) 00487 if (!xdr_translate(x, *iter)) 00488 b = false; 00489 return b; 00490 } 00491 00492 template <> 00493 xdrproc_t xdr_translator<int>() { return (xdrproc_t)(xdr_int); } 00494 00495 template <> 00496 xdrproc_t xdr_translator<unsigned int>() { return (xdrproc_t)(xdr_u_int); } 00497 00498 template <> 00499 xdrproc_t xdr_translator<long int>() { return (xdrproc_t)(xdr_long); } 00500 00501 template <> 00502 xdrproc_t xdr_translator<unsigned long int>() { return (xdrproc_t)(xdr_u_long); } 00503 00504 template <> 00505 xdrproc_t xdr_translator<short int>() { return (xdrproc_t)(xdr_short); } 00506 00507 template <> 00508 xdrproc_t xdr_translator<unsigned short int>() { return (xdrproc_t)(xdr_u_short); } 00509 00510 template <> 00511 xdrproc_t xdr_translator<char>() { return (xdrproc_t)(xdr_char); } 00512 00513 template <> 00514 xdrproc_t xdr_translator<signed char>() { return (xdrproc_t)(xdr_char); } 00515 00516 template <> 00517 xdrproc_t xdr_translator<unsigned char>() { return (xdrproc_t)(xdr_u_char); } 00518 00519 template <> 00520 xdrproc_t xdr_translator<float>() { return (xdrproc_t)(xdr_float); } 00521 00522 template <> 00523 xdrproc_t xdr_translator<double>() { return (xdrproc_t)(xdr_double); } 00524 00525 // FIXME - no XDR love for long doubles? 00526 template <> 00527 xdrproc_t xdr_translator<long double>() { return (xdrproc_t)(xdr_double); } 00528 00529 } // end anonymous namespace 00530 00531 #endif 00532 00533 template <typename T> 00534 void Xdr::do_read(T& a) { 00535 *in >> a; 00536 in->getline(comm, comm_len); 00537 } 00538 00539 template <typename T> 00540 void Xdr::do_read(std::complex<T>& a) { 00541 T r, i; 00542 *in >> r >> i; 00543 a = std::complex<T>(r,i); 00544 in->getline(comm, comm_len); 00545 } 00546 00547 template <> 00548 void Xdr::do_read(std::string& a) { 00549 in->getline(comm, comm_len); 00550 00551 a = ""; 00552 00553 for (unsigned int c=0; c<std::strlen(comm); c++) 00554 { 00555 if (comm[c] == '\t') 00556 break; 00557 a.push_back(comm[c]); 00558 } 00559 } 00560 00561 template <typename T> 00562 void Xdr::do_read(std::vector<T>& a) { 00563 unsigned int length=0; 00564 data(length, "# vector length"); 00565 a.resize(length); 00566 00567 for (unsigned int i=0; i<a.size(); i++) 00568 { 00569 libmesh_assert(in.get()); 00570 libmesh_assert (in->good()); 00571 *in >> a[i]; 00572 } 00573 in->getline(comm, comm_len); 00574 } 00575 00576 template <typename T> 00577 void Xdr::do_read(std::vector<std::complex<T> >& a) { 00578 unsigned int length=0; 00579 data(length, "# vector length x 2 (complex)"); 00580 a.resize(length); 00581 00582 for (unsigned int i=0; i<a.size(); i++) 00583 { 00584 T r, im; 00585 libmesh_assert(in.get()); 00586 libmesh_assert (in->good()); 00587 *in >> r >> im; 00588 a[i] = std::complex<T>(r,im); 00589 } 00590 in->getline(comm, comm_len); 00591 } 00592 00593 template <typename T> 00594 void Xdr::do_write(T& a) { *out << a; } 00595 00596 template <typename T> 00597 void Xdr::do_write(std::complex<T>& a) { 00598 *out << a.real() << "\t " << a.imag(); 00599 } 00600 00601 template <typename T> 00602 void Xdr::do_write(std::vector<T>& a) { 00603 std::size_t length = a.size(); 00604 data(length, "# vector length"); 00605 00606 for (std::size_t i=0; i<a.size(); i++) 00607 { 00608 libmesh_assert(out.get()); 00609 libmesh_assert (out->good()); 00610 this->do_write(a[i]); 00611 *out << "\t "; 00612 } 00613 } 00614 00615 template <typename T> 00616 void Xdr::do_write(std::vector<std::complex<T> >& a) { 00617 std::size_t length=a.size(); 00618 data(length, "# vector length x 2 (complex)"); 00619 00620 for (std::size_t i=0; i<a.size(); i++) 00621 { 00622 libmesh_assert(out.get()); 00623 libmesh_assert (out->good()); 00624 this->do_write(a[i]); 00625 *out << "\t "; 00626 } 00627 } 00628 00629 00630 00631 template <typename T> 00632 void Xdr::data (T& a, const char* comment_in) 00633 { 00634 switch (mode) 00635 { 00636 case ENCODE: 00637 case DECODE: 00638 { 00639 #ifdef LIBMESH_HAVE_XDR 00640 00641 libmesh_assert (is_open()); 00642 00643 xdr_translate(xdrs, a); 00644 00645 #else 00646 00647 libMesh::err << "ERROR: Functionality is not available." << std::endl 00648 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00649 << std::endl 00650 << "The XDR interface is not available in this installation" 00651 << std::endl; 00652 00653 libmesh_error(); 00654 00655 #endif 00656 return; 00657 } 00658 00659 case READ: 00660 { 00661 libmesh_assert(in.get()); 00662 libmesh_assert (in->good()); 00663 00664 this->do_read(a); 00665 00666 return; 00667 } 00668 00669 case WRITE: 00670 { 00671 libmesh_assert(out.get()); 00672 libmesh_assert (out->good()); 00673 00674 this->do_write(a); 00675 *out << "\t " << comment_in << '\n'; 00676 00677 return; 00678 } 00679 00680 default: 00681 libmesh_error(); 00682 } 00683 } 00684 00685 00686 template <typename T> 00687 void Xdr::data_stream (T *val, const unsigned int len, const unsigned int line_break) 00688 { 00689 switch (mode) 00690 { 00691 case ENCODE: 00692 { 00693 #ifdef LIBMESH_HAVE_XDR 00694 00695 libmesh_assert (this->is_open()); 00696 00697 00698 xdr_vector(xdrs, 00699 (char*) val, 00700 len, 00701 sizeof(unsigned int), 00702 (xdrproc_t) xdr_u_int); 00703 00704 #else 00705 00706 libMesh::err << "ERROR: Functionality is not available." << std::endl 00707 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00708 << std::endl 00709 << "The XDR interface is not available in this installation" 00710 << std::endl; 00711 00712 libmesh_error(); 00713 00714 #endif 00715 return; 00716 } 00717 00718 case DECODE: 00719 { 00720 #ifdef LIBMESH_HAVE_XDR 00721 00722 libmesh_assert (this->is_open()); 00723 00724 if (len > 0) 00725 xdr_vector(xdrs, 00726 (char*) val, 00727 len, 00728 sizeof(unsigned int), 00729 (xdrproc_t) xdr_u_int); 00730 00731 #else 00732 00733 libMesh::err << "ERROR: Functionality is not available." << std::endl 00734 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00735 << std::endl 00736 << "The XDR interface is not available in this installation" 00737 << std::endl; 00738 00739 libmesh_error(); 00740 00741 #endif 00742 return; 00743 } 00744 00745 case READ: 00746 { 00747 libmesh_assert(in.get()); 00748 libmesh_assert (in->good()); 00749 00750 for (unsigned int i=0; i<len; i++) 00751 { 00752 libmesh_assert(in.get()); 00753 libmesh_assert (in->good()); 00754 *in >> val[i]; 00755 } 00756 00757 return; 00758 } 00759 00760 case WRITE: 00761 { 00762 libmesh_assert(out.get()); 00763 libmesh_assert (out->good()); 00764 00765 if (line_break == libMesh::invalid_uint) 00766 for (unsigned int i=0; i<len; i++) 00767 { 00768 libmesh_assert(out.get()); 00769 libmesh_assert (out->good()); 00770 *out << val[i] << " "; 00771 } 00772 else 00773 { 00774 unsigned int cnt=0; 00775 while (cnt < len) 00776 { 00777 for (unsigned int i=0; i<std::min(line_break,len); i++) 00778 { 00779 libmesh_assert(out.get()); 00780 libmesh_assert (out->good()); 00781 *out << val[cnt++] << " "; 00782 } 00783 libmesh_assert(out.get()); 00784 libmesh_assert (out->good()); 00785 *out << '\n'; 00786 } 00787 } 00788 00789 return; 00790 } 00791 00792 default: 00793 libmesh_error(); 00794 } 00795 } 00796 00797 00798 00799 template <> 00800 void Xdr::data_stream (double *val, const unsigned int len, const unsigned int line_break) 00801 { 00802 switch (mode) 00803 { 00804 case ENCODE: 00805 case DECODE: 00806 { 00807 #ifdef LIBMESH_HAVE_XDR 00808 00809 libmesh_assert (this->is_open()); 00810 00811 if (len > 0) 00812 xdr_vector(xdrs, 00813 (char*) val, 00814 len, 00815 sizeof(double), 00816 (xdrproc_t) xdr_double); 00817 00818 #else 00819 00820 libMesh::err << "ERROR: Functionality is not available." << std::endl 00821 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00822 << std::endl 00823 << "The XDR interface is not available in this installation" 00824 << std::endl; 00825 00826 libmesh_error(); 00827 00828 #endif 00829 return; 00830 } 00831 00832 case READ: 00833 { 00834 libmesh_assert(in.get()); 00835 libmesh_assert (in->good()); 00836 00837 for (unsigned int i=0; i<len; i++) 00838 { 00839 libmesh_assert(in.get()); 00840 libmesh_assert (in->good()); 00841 *in >> val[i]; 00842 } 00843 00844 return; 00845 } 00846 00847 case WRITE: 00848 { 00849 libmesh_assert(out.get()); 00850 libmesh_assert (out->good()); 00851 00852 // Save stream flags 00853 std::ios_base::fmtflags out_flags = out->flags(); 00854 00855 // We will use scientific notation with a precision of 16 00856 // digits in the following output. The desired precision and 00857 // format will automatically determine the width. 00858 *out << std::scientific 00859 << std::setprecision(16); 00860 00861 if (line_break == libMesh::invalid_uint) 00862 for (unsigned int i=0; i<len; i++) 00863 { 00864 libmesh_assert(out.get()); 00865 libmesh_assert (out->good()); 00866 *out << val[i] << ' '; 00867 } 00868 else 00869 { 00870 unsigned int cnt=0; 00871 while (cnt < len) 00872 { 00873 for (unsigned int i=0; i<std::min(line_break,len); i++) 00874 { 00875 libmesh_assert(out.get()); 00876 libmesh_assert (out->good()); 00877 *out << val[cnt++] << ' '; 00878 } 00879 libmesh_assert(out.get()); 00880 libmesh_assert (out->good()); 00881 *out << '\n'; 00882 } 00883 } 00884 00885 // Restore stream flags 00886 out->flags(out_flags); 00887 00888 return; 00889 } 00890 00891 default: 00892 libmesh_error(); 00893 } 00894 } 00895 00896 00897 template <> 00898 void Xdr::data_stream (float *val, const unsigned int len, const unsigned int line_break) 00899 { 00900 switch (mode) 00901 { 00902 case ENCODE: 00903 case DECODE: 00904 { 00905 #ifdef LIBMESH_HAVE_XDR 00906 00907 libmesh_assert (this->is_open()); 00908 00909 if (len > 0) 00910 xdr_vector(xdrs, 00911 (char*) val, 00912 len, 00913 sizeof(float), 00914 (xdrproc_t) xdr_float); 00915 00916 #else 00917 00918 libMesh::err << "ERROR: Functionality is not available." << std::endl 00919 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 00920 << std::endl 00921 << "The XDR interface is not available in this installation" 00922 << std::endl; 00923 00924 libmesh_error(); 00925 00926 #endif 00927 return; 00928 } 00929 00930 case READ: 00931 { 00932 libmesh_assert(in.get()); 00933 libmesh_assert (in->good()); 00934 00935 for (unsigned int i=0; i<len; i++) 00936 { 00937 libmesh_assert(in.get()); 00938 libmesh_assert (in->good()); 00939 *in >> val[i]; 00940 } 00941 00942 return; 00943 } 00944 00945 case WRITE: 00946 { 00947 libmesh_assert(out.get()); 00948 libmesh_assert (out->good()); 00949 00950 // Save stream flags 00951 std::ios_base::fmtflags out_flags = out->flags(); 00952 00953 // We will use scientific notation with a precision of 16 00954 // digits in the following output. The desired precision and 00955 // format will automatically determine the width. 00956 *out << std::scientific 00957 << std::setprecision(16); 00958 00959 if (line_break == libMesh::invalid_uint) 00960 for (unsigned int i=0; i<len; i++) 00961 { 00962 libmesh_assert(out.get()); 00963 libmesh_assert (out->good()); 00964 *out << val[i] << ' '; 00965 } 00966 else 00967 { 00968 unsigned int cnt=0; 00969 while (cnt < len) 00970 { 00971 for (unsigned int i=0; i<std::min(line_break,len); i++) 00972 { 00973 libmesh_assert(out.get()); 00974 libmesh_assert (out->good()); 00975 *out << val[cnt++] << ' '; 00976 } 00977 libmesh_assert(out.get()); 00978 libmesh_assert (out->good()); 00979 *out << '\n'; 00980 } 00981 } 00982 00983 // Restore stream flags 00984 out->flags(out_flags); 00985 00986 return; 00987 } 00988 00989 default: 00990 libmesh_error(); 00991 } 00992 } 00993 template <> 00994 void Xdr::data_stream (long double *val, const unsigned int len, const unsigned int line_break) 00995 { 00996 switch (mode) 00997 { 00998 case ENCODE: 00999 case DECODE: 01000 { 01001 #ifdef LIBMESH_HAVE_XDR 01002 01003 libmesh_assert (this->is_open()); 01004 01005 // FIXME[JWP]: How to implement this for long double? Mac OS 01006 // X defines 'xdr_quadruple' but AFAICT, it does not exist for 01007 // Linux... for now, reading/writing XDR files with long 01008 // doubles drops back to double precision, but you can still 01009 // write long double ASCII files of course. 01010 // if (len > 0) 01011 // xdr_vector(xdrs, 01012 // (char*) val, 01013 // len, 01014 // sizeof(double), 01015 // (xdrproc_t) xdr_quadruple); 01016 01017 if (len > 0) 01018 { 01019 std::vector<double> io_buffer (len); 01020 01021 // Fill io_buffer if we are writing. 01022 if (mode == ENCODE) 01023 for (unsigned int i=0, cnt=0; i<len; i++) 01024 io_buffer[cnt++] = val[i]; 01025 01026 xdr_vector(xdrs, 01027 (char*) &io_buffer[0], 01028 len, 01029 sizeof(double), 01030 (xdrproc_t) xdr_double); 01031 01032 // Fill val array if we are reading. 01033 if (mode == DECODE) 01034 for (unsigned int i=0, cnt=0; i<len; i++) 01035 { 01036 val[i] = io_buffer[cnt++]; 01037 } 01038 } 01039 01040 #else 01041 01042 libMesh::err << "ERROR: Functionality is not available." << std::endl 01043 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 01044 << std::endl 01045 << "The XDR interface is not available in this installation" 01046 << std::endl; 01047 01048 libmesh_error(); 01049 01050 #endif 01051 return; 01052 } 01053 01054 case READ: 01055 { 01056 libmesh_assert(in.get()); 01057 libmesh_assert (in->good()); 01058 01059 for (unsigned int i=0; i<len; i++) 01060 { 01061 libmesh_assert(in.get()); 01062 libmesh_assert (in->good()); 01063 *in >> val[i]; 01064 } 01065 01066 return; 01067 } 01068 01069 case WRITE: 01070 { 01071 libmesh_assert(out.get()); 01072 libmesh_assert (out->good()); 01073 01074 // Save stream flags 01075 std::ios_base::fmtflags out_flags = out->flags(); 01076 01077 // We will use scientific notation with a precision of 16 01078 // digits in the following output. The desired precision and 01079 // format will automatically determine the width. 01080 *out << std::scientific 01081 << std::setprecision(16); 01082 01083 if (line_break == libMesh::invalid_uint) 01084 for (unsigned int i=0; i<len; i++) 01085 { 01086 libmesh_assert(out.get()); 01087 libmesh_assert (out->good()); 01088 *out << val[i] << ' '; 01089 } 01090 else 01091 { 01092 unsigned int cnt=0; 01093 while (cnt < len) 01094 { 01095 for (unsigned int i=0; i<std::min(line_break,len); i++) 01096 { 01097 libmesh_assert(out.get()); 01098 libmesh_assert (out->good()); 01099 *out << val[cnt++] << ' '; 01100 } 01101 libmesh_assert(out.get()); 01102 libmesh_assert (out->good()); 01103 *out << '\n'; 01104 } 01105 } 01106 01107 // Restore stream flags 01108 out->flags(out_flags); 01109 01110 return; 01111 } 01112 01113 default: 01114 libmesh_error(); 01115 } 01116 } 01117 01118 01119 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 01120 template <> 01121 void Xdr::data_stream (std::complex<double> *val, const unsigned int len, const unsigned int line_break) 01122 { 01123 switch (mode) 01124 { 01125 case ENCODE: 01126 case DECODE: 01127 { 01128 #ifdef LIBMESH_HAVE_XDR 01129 01130 libmesh_assert (this->is_open()); 01131 01132 01133 if (len > 0) 01134 { 01135 std::vector<double> io_buffer (2*len); 01136 01137 // Fill io_buffer if we are writing. 01138 if (mode == ENCODE) 01139 for (unsigned int i=0, cnt=0; i<len; i++) 01140 { 01141 io_buffer[cnt++] = val[i].real(); 01142 io_buffer[cnt++] = val[i].imag(); 01143 } 01144 01145 xdr_vector(xdrs, 01146 (char*) &io_buffer[0], 01147 2*len, 01148 sizeof(double), 01149 (xdrproc_t) xdr_double); 01150 01151 // Fill val array if we are reading. 01152 if (mode == DECODE) 01153 for (unsigned int i=0, cnt=0; i<len; i++) 01154 { 01155 double re = io_buffer[cnt++]; 01156 double im = io_buffer[cnt++]; 01157 val[i] = std::complex<double>(re,im); 01158 } 01159 } 01160 #else 01161 01162 libMesh::err << "ERROR: Functionality is not available." << std::endl 01163 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 01164 << std::endl 01165 << "The XDR interface is not available in this installation" 01166 << std::endl; 01167 01168 libmesh_error(); 01169 01170 #endif 01171 return; 01172 } 01173 01174 case READ: 01175 { 01176 libmesh_assert(in.get()); 01177 libmesh_assert (in->good()); 01178 01179 for (unsigned int i=0; i<len; i++) 01180 { 01181 libmesh_assert(in.get()); 01182 libmesh_assert (in->good()); 01183 double re, im; 01184 *in >> re >> im; 01185 val[i] = std::complex<double>(re,im); 01186 } 01187 01188 return; 01189 } 01190 01191 case WRITE: 01192 { 01193 libmesh_assert(out.get()); 01194 libmesh_assert (out->good()); 01195 01196 // Save stream flags 01197 std::ios_base::fmtflags out_flags = out->flags(); 01198 01199 // We will use scientific notation with a precision of 16 01200 // digits in the following output. The desired precision and 01201 // format will automatically determine the width. 01202 *out << std::scientific 01203 << std::setprecision(16); 01204 01205 if (line_break == libMesh::invalid_uint) 01206 for (unsigned int i=0; i<len; i++) 01207 { 01208 libmesh_assert(out.get()); 01209 libmesh_assert (out->good()); 01210 *out << val[i].real() << ' '; 01211 *out << val[i].imag() << ' '; 01212 } 01213 else 01214 { 01215 unsigned int cnt=0; 01216 while (cnt < len) 01217 { 01218 for (unsigned int i=0; i<std::min(line_break,len); i++) 01219 { 01220 libmesh_assert(out.get()); 01221 libmesh_assert (out->good()); 01222 *out << val[cnt].real() << ' '; 01223 *out << val[cnt].imag() << ' '; 01224 cnt++; 01225 } 01226 libmesh_assert(out.get()); 01227 libmesh_assert (out->good()); 01228 *out << '\n'; 01229 } 01230 } 01231 01232 // Restore stream flags 01233 out->flags(out_flags); 01234 01235 return; 01236 } 01237 01238 default: 01239 libmesh_error(); 01240 } 01241 } 01242 01243 template <> 01244 void Xdr::data_stream (std::complex<long double> *val, const unsigned int len, const unsigned int line_break) 01245 { 01246 switch (mode) 01247 { 01248 case ENCODE: 01249 case DECODE: 01250 { 01251 #ifdef LIBMESH_HAVE_XDR 01252 01253 libmesh_assert (this->is_open()); 01254 01255 // FIXME[JWP]: How to implement this for long double? Mac OS 01256 // X defines 'xdr_quadruple' but AFAICT, it does not exist for 01257 // Linux... for now, reading/writing XDR files with long 01258 // doubles drops back to double precision, but you can still 01259 // write long double ASCII files of course. 01260 01261 if (len > 0) 01262 { 01263 std::vector<double> io_buffer (2*len); 01264 01265 // Fill io_buffer if we are writing. 01266 if (mode == ENCODE) 01267 for (unsigned int i=0, cnt=0; i<len; i++) 01268 { 01269 io_buffer[cnt++] = val[i].real(); 01270 io_buffer[cnt++] = val[i].imag(); 01271 } 01272 01273 xdr_vector(xdrs, 01274 (char*) &io_buffer[0], 01275 2*len, 01276 sizeof(double), 01277 (xdrproc_t) xdr_double); 01278 01279 // Fill val array if we are reading. 01280 if (mode == DECODE) 01281 for (unsigned int i=0, cnt=0; i<len; i++) 01282 { 01283 double re = io_buffer[cnt++]; 01284 double im = io_buffer[cnt++]; 01285 val[i] = std::complex<long double>(re, im); 01286 } 01287 } 01288 #else 01289 01290 libMesh::err << "ERROR: Functionality is not available." << std::endl 01291 << "Make sure LIBMESH_HAVE_XDR is defined at build time" 01292 << std::endl 01293 << "The XDR interface is not available in this installation" 01294 << std::endl; 01295 01296 libmesh_error(); 01297 01298 #endif 01299 return; 01300 } 01301 01302 case READ: 01303 { 01304 libmesh_assert(in.get()); 01305 libmesh_assert (in->good()); 01306 01307 for (unsigned int i=0; i<len; i++) 01308 { 01309 libmesh_assert(in.get()); 01310 libmesh_assert (in->good()); 01311 long double re, im; 01312 *in >> re >> im; 01313 val[i] = std::complex<long double>(re,im); 01314 } 01315 01316 return; 01317 } 01318 01319 case WRITE: 01320 { 01321 libmesh_assert(out.get()); 01322 libmesh_assert (out->good()); 01323 01324 01325 // Save stream flags 01326 std::ios_base::fmtflags out_flags = out->flags(); 01327 01328 // We will use scientific notation with a precision of 01329 // 'digits10' digits in the following output. The desired 01330 // precision and format will automatically determine the 01331 // width. Note: digit10 is the number of digits (in decimal 01332 // base) that can be represented without change. Equivalent 01333 // to FLT_DIG, DBL_DIG or LDBL_DIG for floating types. 01334 *out << std::scientific 01335 << std::setprecision(std::numeric_limits<long double>::digits10); 01336 01337 if (line_break == libMesh::invalid_uint) 01338 for (unsigned int i=0; i<len; i++) 01339 { 01340 libmesh_assert(out.get()); 01341 libmesh_assert (out->good()); 01342 *out << val[i].real() << ' ' << val[i].imag() << ' '; 01343 } 01344 else 01345 { 01346 unsigned int cnt=0; 01347 while (cnt < len) 01348 { 01349 for (unsigned int i=0; i<std::min(line_break,len); i++) 01350 { 01351 libmesh_assert(out.get()); 01352 libmesh_assert (out->good()); 01353 *out << val[cnt].real() << ' ' << val[cnt].imag() << ' '; 01354 cnt++; 01355 } 01356 libmesh_assert(out.get()); 01357 libmesh_assert (out->good()); 01358 *out << '\n'; 01359 } 01360 } 01361 01362 // Restore stream flags 01363 out->flags(out_flags); 01364 01365 return; 01366 } 01367 01368 default: 01369 libmesh_error(); 01370 } 01371 } 01372 #endif // # LIBMESH_USE_COMPLEX_NUMBERS 01373 01374 void Xdr::comment (std::string &comment_in) 01375 { 01376 switch (mode) 01377 { 01378 case ENCODE: 01379 case DECODE: 01380 { 01381 return; 01382 } 01383 01384 case READ: 01385 { 01386 libmesh_assert(in.get()); 01387 libmesh_assert (in->good()); 01388 in->getline(comm, comm_len); 01389 return; 01390 } 01391 01392 case WRITE: 01393 { 01394 libmesh_assert(out.get()); 01395 libmesh_assert (out->good()); 01396 *out << "\t " << comment_in << '\n'; 01397 return; 01398 } 01399 01400 default: 01401 libmesh_error(); 01402 } 01403 } 01404 01405 01406 #undef xdr_REAL 01407 01408 01409 // 01410 template void Xdr::data<int> (int&, const char*); 01411 template void Xdr::data<unsigned int> (unsigned int&, const char*); 01412 template void Xdr::data<unsigned short int> (unsigned short int&, const char*); 01413 template void Xdr::data<short int> (short int&, const char*); 01414 template void Xdr::data<unsigned long int> (unsigned long int&, const char*); 01415 template void Xdr::data<long int> (long int&, const char*); 01416 template void Xdr::data<char> (char&, const char*); 01417 template void Xdr::data<signed char> (signed char&, const char*); 01418 template void Xdr::data<unsigned char> (unsigned char&, const char*); 01419 template void Xdr::data<float> (float&, const char*); 01420 template void Xdr::data<double> (double&, const char*); 01421 template void Xdr::data<long double> (long double&, const char*); 01422 template void Xdr::data<std::complex<float> > (std::complex<float>&, const char*); 01423 template void Xdr::data<std::complex<double> > (std::complex<double>&, const char*); 01424 template void Xdr::data<std::complex<long double> > (std::complex<long double>&, const char*); 01425 template void Xdr::data<std::string> (std::string&, const char*); 01426 template void Xdr::data<std::vector<int> > (std::vector<int>&, const char*); 01427 template void Xdr::data<std::vector<unsigned int> > (std::vector<unsigned int>&, const char*); 01428 template void Xdr::data<std::vector<short int> > (std::vector<short int>&, const char*); 01429 template void Xdr::data<std::vector<unsigned short int> > (std::vector<unsigned short int>&, const char*); 01430 template void Xdr::data<std::vector<long int> > (std::vector<long int>&, const char*); 01431 template void Xdr::data<std::vector<unsigned long int> > (std::vector<unsigned long int>&, const char*); 01432 template void Xdr::data<std::vector<char> > (std::vector<char>&, const char*); 01433 template void Xdr::data<std::vector<signed char> > (std::vector<signed char>&, const char*); 01434 template void Xdr::data<std::vector<unsigned char> > (std::vector<unsigned char>&, const char*); 01435 template void Xdr::data<std::vector<float> > (std::vector<float>&, const char*); 01436 template void Xdr::data<std::vector<double> > (std::vector<double>&, const char*); 01437 template void Xdr::data<std::vector<long double> > (std::vector<long double>&, const char*); 01438 template void Xdr::data<std::vector<std::complex<float> > > (std::vector<std::complex<float> >&, const char*); 01439 template void Xdr::data<std::vector<std::complex<double> > > (std::vector<std::complex<double> >&, const char*); 01440 template void Xdr::data<std::vector<std::complex<long double> > > (std::vector<std::complex<long double> >&, const char*); 01441 template void Xdr::data_stream<int> (int *val, const unsigned int len, const unsigned int line_break); 01442 template void Xdr::data_stream<unsigned short int> (unsigned short int *val, const unsigned int len, const unsigned int line_break); 01443 template void Xdr::data_stream<unsigned int> (unsigned int *val, const unsigned int len, const unsigned int line_break); 01444 template void Xdr::data_stream<unsigned long int> (unsigned long int *val, const unsigned int len, const unsigned int line_break); 01445 01446 01447 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC
Hosted By: