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