Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 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 :
20 : #ifndef LIBMESH_XDR_CXX_H
21 : #define LIBMESH_XDR_CXX_H
22 :
23 : // Local includes
24 : #include "libmesh/libmesh_common.h"
25 : #include "libmesh/libmesh.h"
26 : #include "libmesh/enum_xdr_mode.h" // READ, WRITE, etc.
27 :
28 : // C++ includes
29 : #include <memory>
30 : #include <cstdio> // FILE
31 : #ifdef LIBMESH_HAVE_XDR
32 : // I see a redundant declaration warning here on Ubuntu 20.10
33 : #include "libmesh/ignore_warnings.h"
34 : # include <rpc/rpc.h>
35 : # include <rpc/xdr.h>
36 : #include "libmesh/restore_warnings.h"
37 : #endif
38 :
39 : #include <complex>
40 : #include <iosfwd>
41 : #include <vector>
42 : #include <string>
43 : #include <string_view>
44 :
45 : const unsigned int xdr_MAX_STRING_LENGTH=256;
46 :
47 : #ifndef LIBMESH_DEFAULT_SINGLE_PRECISION
48 : #define xdr_REAL xdr_double
49 : #else
50 : #define xdr_REAL xdr_float
51 : #endif
52 :
53 : namespace libMesh
54 : {
55 :
56 : /**
57 : * This class implements a C++ interface to the XDR
58 : * (eXternal Data Representation) format. XDR is useful for
59 : * creating platform-independent binary files. This class was
60 : * created to handle equation system output as a replacement for
61 : * XdrIO since that is somewhat limited.
62 : *
63 : * \author Benjamin Kirk
64 : * \date 2003
65 : * \brief C++ interface for the XDR (eXternal Data Representation) format.
66 : */
67 : class Xdr
68 : {
69 :
70 : public:
71 :
72 : /**
73 : * File-based constructor. Takes the filename and the mode.
74 : * Valid modes are ENCODE, DECODE, READ, and WRITE.
75 : */
76 : Xdr (std::string name="", const XdrMODE m=UNKNOWN);
77 :
78 : /**
79 : * Output stream based constructor.
80 : * Assumes mode WRITE.
81 : */
82 : Xdr (std::ostream & stream);
83 : /**
84 : * Input stream based constructor.
85 : * Assumes mode READ.
86 : */
87 : Xdr (std::istream & stream);
88 :
89 : /**
90 : * Destructor. Closes the file if it is open.
91 : */
92 : ~Xdr ();
93 :
94 : /**
95 : * Opens the file.
96 : */
97 : void open (std::string name);
98 :
99 : /**
100 : * Closes the file if it is open.
101 : */
102 : void close();
103 :
104 : /**
105 : * \returns \p true if the Xdr file is open, false
106 : * if it is closed.
107 : */
108 : bool is_open() const;
109 :
110 : /**
111 : * \returns \p true if the Xdr file being read is at End-Of-File.
112 : *
113 : * \note This is \e not a const method - the only portable way to
114 : * test for an impending EOF is to peek at the next byte of the file
115 : * first, which may set the eof flag on the istream.
116 : */
117 : bool is_eof();
118 :
119 : /**
120 : * \returns \p true if the file is opened in a reading
121 : * state, false otherwise.
122 : */
123 34404 : bool reading() const { return ((mode == DECODE) || (mode == READ)); }
124 :
125 : /**
126 : * \returns \p true if the file is opened in a writing
127 : * state, false otherwise.
128 : */
129 18230 : bool writing() const { return ((mode == ENCODE) || (mode == WRITE)); }
130 :
131 : /**
132 : * \returns The mode used to access the file. Valid modes
133 : * are ENCODE, DECODE, READ, or WRITE.
134 : */
135 : XdrMODE access_mode () const { return mode; }
136 :
137 : // Data access methods
138 :
139 : /**
140 : * Inputs or outputs a single value.
141 : */
142 : template <typename T>
143 : void data(T & a, std::string_view comment="");
144 :
145 : /**
146 : * Same, but provides an \p ostream like interface.
147 : */
148 : template <typename T>
149 182623 : Xdr & operator << (T & a) { libmesh_assert (writing()); data(a); return *this; }
150 :
151 : /**
152 : * Same, but provides an \p istream like interface.
153 : */
154 : template <typename T>
155 1089809 : Xdr & operator >> (T & a) { libmesh_assert (reading()); data(a); return *this; }
156 :
157 : /**
158 : * Inputs or outputs a raw data stream.
159 : */
160 : template <typename T>
161 : void data_stream (T * val, const unsigned int len, const unsigned int line_break=libMesh::invalid_uint);
162 :
163 : /**
164 : * Writes or reads (ignores) a comment line.
165 : */
166 : void comment (std::string &);
167 :
168 : /**
169 : * Sets the version of the file that is being read
170 : */
171 19490 : void set_version(int ver) { version_number = ver; }
172 :
173 : /**
174 : * Gets the version of the file that is being read
175 : */
176 162000 : int version() const { return version_number; }
177 :
178 : private:
179 :
180 : /**
181 : * Helper method for reading different data types
182 : */
183 : template <typename T>
184 : void do_read(T & a);
185 :
186 : template <typename T>
187 : void do_read(std::complex<T> & a);
188 :
189 : template <typename T>
190 : void do_read(std::vector<T> & a);
191 :
192 : template <typename T>
193 : void do_read(std::vector<std::complex<T>> & a);
194 :
195 : /**
196 : * Helper method for writing different data types
197 : */
198 : template <typename T>
199 : void do_write(T & a);
200 :
201 : template <typename T>
202 : void do_write(std::complex<T> & a);
203 :
204 : template <typename T>
205 : void do_write(std::vector<T> & a);
206 :
207 : template <typename T>
208 : void do_write(std::vector<std::complex<T>> & a);
209 :
210 : /**
211 : * Helper method for complex types
212 : */
213 : template <typename T>
214 : void _complex_data_stream (std::complex<T> * val, const unsigned int len,
215 : const unsigned int line_break);
216 :
217 : /**
218 : * Helper method for extended FP types
219 : */
220 : template <typename XFP>
221 : void _xfp_data_stream (XFP * val, const unsigned int len,
222 : #ifdef LIBMESH_HAVE_XDR
223 : xdrproc_t
224 : #else
225 : void *
226 : #endif
227 : xdr_proc,
228 : const unsigned int line_break,
229 : const int n_digits);
230 :
231 : /**
232 : * The mode used for accessing the file.
233 : */
234 : const XdrMODE mode;
235 :
236 : /**
237 : * The file name
238 : */
239 : std::string file_name;
240 :
241 : #ifdef LIBMESH_HAVE_XDR
242 :
243 : /**
244 : * Pointer to the standard XDR struct. See the standard header file
245 : * rpc/rpc.h for more information.
246 : */
247 : std::unique_ptr<XDR> xdrs;
248 :
249 : /**
250 : * File pointer.
251 : */
252 : FILE * fp;
253 :
254 : #endif
255 :
256 : /**
257 : * The input file stream.
258 : */
259 : std::unique_ptr<std::istream> in;
260 :
261 : /**
262 : * The output file stream.
263 : */
264 : std::unique_ptr<std::ostream> out;
265 :
266 : /**
267 : * A buffer to put comment strings into.
268 : */
269 : const int comm_len;
270 : char comm[xdr_MAX_STRING_LENGTH];
271 :
272 : /**
273 : * Are we reading/writing zipped files?
274 : */
275 : bool gzipped_file, bzipped_file, xzipped_file;
276 :
277 : /**
278 : * Version of the file being read
279 : */
280 : int version_number;
281 : };
282 :
283 :
284 : } // namespace libMesh
285 :
286 :
287 : #endif // LIBMESH_XDR_CXX_H
|