MADNESS 0.10.1
text_fstream_archive.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_TEXT_FSTREAM_ARCHIVE_H__INCLUDED
33#define MADNESS_WORLD_TEXT_FSTREAM_ARCHIVE_H__INCLUDED
34
35/**
36 \file text_fstream_archive.h
37 \brief Implements an archive wrapping text filestream.
38 \ingroup serialization
39*/
40
41#include <type_traits>
42#include <fstream>
43#include <cstring>
45#include <madness/world/print.h> // this injects operator<<(std::ostream,T) for common Ts
46
47namespace madness {
48 namespace archive {
49
50 /// \addtogroup serialization
51 /// @{
52
53 /// Wraps an archive around a text filestream for output.
55 mutable std::ofstream os; ///< The filestream.
56
57 public:
58 /// Default constructor.
59
60 /// The filename and open modes are optional here; they can be
61 /// specified later by calling \c open().
62 /// \param[in] filename Name of the file to write to.
63 /// \param[in] mode I/O attributes for opening the file.
64 TextFstreamOutputArchive(const char* filename = nullptr,
65 std::ios_base::openmode mode=std::ios_base::binary | std::ios_base::out | std::ios_base::trunc)
66 {
67 if (filename)
68 open(filename, mode);
69 }
70
71 /// Stores the cookie for runtime type-checking into the archive as a tag.
72
73 /// \tparam T The type of data to be stored between the tags.
74 template <class T>
75 void store_start_tag() const {
76 std::size_t bufsize=256;
77 char tag[bufsize];
78 unsigned char cookie = archive_typeinfo<T>::cookie;
79 snprintf(tag,bufsize,"<t%d>", cookie);
80 os << tag << std::endl;
81 MAD_ARCHIVE_DEBUG(std::cout << "textarchive: tag = " << tag << std::endl);
82 }
83
84 /// Closes the "cookie" tag for runtime type-checking.
85
86 /// \tparam T The type of data to be stored between the tags.
87 template <class T>
88 void store_end_tag() const {
89 std::size_t bufsize=256;
90 char tag[bufsize];
91 unsigned char cookie = archive_typeinfo<T>::cookie;
92 snprintf(tag,bufsize,"</t%d>",cookie);
93 os << tag << std::endl;
94 }
95
96 /// Store data to the filestream.
97
98 /// The function only appears (due to \c enable_if) if \c T is
99 /// serializable.
100 /// \tparam T The type of data to be written.
101 /// \param[in] t Location of the data to be written.
102 /// \param[in] n The number of data items to be written.
103 template <class T>
104 typename std::enable_if< madness::is_ostreammable_v<T> >::type
105 store(const T* t, long n) const {
106 using madness::operators::operator<<;
107 for (long i=0; i<n; ++i)
108 os << t[i] << std::endl;
109 }
110
111 /// Store a character string, escaping '&', '<' and '> along the way.
112
113 /// \param[in] t The character string.
114 void store(const char* t, long /*n*/) const;
115
116 /// Store a character string, without escaping characters.
117
118 /// \param[in] t The character string.
119 /// \param[in] n The number of characters to store.
120 void store(const unsigned char* t, long n) const {
121 for (long i=0; i<n; ++i)
122 os << (unsigned int) t[i] << std::endl;
123 }
124
125 /// Open the filestream.
126
127 /// \param[in] filename The name of the file.
128 /// \param[in] mode I/O attributes for opening the file.
129 void open(const char* filename, std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc);
130
131 /// Close the filestream.
132 void close();
133
134 /// Flush the filestream.
135 void flush() {
136 if (os.is_open())
137 os.flush();
138 }
139
140 /// Destructor.
144 }; // class TextFstreamOutputArchive
145
146
147 /// Wraps an archive around a text filestream for input.
149 private:
150 mutable std::ifstream is; ///< The filestream.
151
152 /// Eat the EOL after each entry to enable a `char`-by-`char` read of strings.
153 void eat_eol() const;
154
155 public:
156 /// Default constructor.
157
158 /// The filename and open modes are optional here; they can be
159 /// specified later by calling \c open().
160 /// \param[in] filename Name of the file to read from.
161 /// \param[in] mode I/O attributes for opening the file.
162 TextFstreamInputArchive(const char* filename = nullptr,
163 std::ios_base::openmode mode = std::ios_base::in)
164 {
165 if (filename)
166 open(filename, mode);
167 }
168
169 /// Check the "cookie" tag in the archive for runtime type-checking.
170
171 /// \tparam T The expected data type.
172 /// \throw MadnessException if the tag does not match that of the
173 /// expected type.
174 template <class T>
175 void check_start_tag(bool end=false) const {
176 std::size_t bufsize=256;
177 char tag[bufsize], ftag[bufsize];
178 is.getline(ftag,bufsize);
179 unsigned char cookie = archive_typeinfo<T>::cookie;
180 if (end)
181 snprintf(tag,bufsize,"</t%d>",cookie);
182 else
183 snprintf(tag,bufsize,"<t%d>",cookie);
184
185 if (strcmp(tag,ftag) != 0) {
186 std::cout << "TextFstreamInputArchive: type mismatch: expected=" << tag
187 << " "
188 << archive_type_names[cookie]
189 << " "
190 << " got=" << ftag << std::endl;
191 MADNESS_EXCEPTION("TextFstreamInputArchive: check_tag: types do not match/corrupt file", 1);
192 }
193 }
194
195 /// Read the closing "cookie" tag.
196
197 /// \tparam T The expected data type between the tags.
198 template <class T>
199 inline void check_end_tag() const {
200 check_start_tag<T>(true);
201 }
202
203 /// Load from the filestream.
204
205 /// The function only appears (due to \c enable_if) if \c T is
206 /// serializable.
207 /// \tparam T The type of data to be read.
208 /// \param[out] t Where to put the loaded data.
209 /// \param[in] n The number of data items to be loaded.
210 template <class T>
211 typename std::enable_if< madness::is_istreammable_v<T> >::type
212 load(T* t, long n) const {
213 using madness::operators::operator>>;
214 for (long i=0; i<n; ++i) is >> t[i];
215 eat_eol();
216 }
217
218 /// Load characters from the filestream, interpreting escaped characters along the way.
219
220 /// \param[out] t Where to put the loaded characters.
221 /// \param[in] n The number of characters to be loaded.
222 void load(unsigned char* t, long n) const;
223
224 /// Load characters from the filestream, without converting escaped characters.
225
226 /// \param[out] t Where to put the loaded characters.
227 /// \param[in] n The number of characters to be loaded.
228 void load(char* t, long n) const;
229
230 /// Open the filestream.
231
232 /// \param[in] filename The name of the file.
233 /// \param[in] mode I/O attributes for opening the file.
234 void open(const char* filename,
235 std::ios_base::openmode mode = std::ios_base::in);
236
237 /// Close the filestream.
238 void close() {
239 is.close();
240 }
241 }; // class TextFstreamInputArchive
242
243 /// Implement pre/postamble storage routines for a \c TextFstreamOutputArchive.
244
245 /// \tparam T The type to be stored.
246 template <class T>
248 /// Write the preamble to the archive.
249
250 /// \param[in] ar The archive.
252 ar.store_start_tag<T>();
253 }
254
255 /// Write the postamble to the archive.
256
257 /// \param[in] ar The archive.
258 static inline void postamble_store(const TextFstreamOutputArchive& ar) {
259 ar.store_end_tag<T>();
260 }
261 }; // struct ArchivePrePostImpl<TextFstreamOutputArchive,T>
262
263 /// Implement pre/postamble load routines for a \c TextFstreamInputArchive.
264
265 /// \tparam T The expected type to be loaded.
266 template <class T>
268 /// Load the preamble and perform type-checking.
269
270 /// \param[in] ar The archive.
271 static inline void preamble_load(const TextFstreamInputArchive& ar) {
272 ar.check_start_tag<T>();
273 }
274
275 /// Load the postamble and perform type-checking.
276
277 /// \param[in] ar The archive.
278 static inline void postamble_load(const TextFstreamInputArchive& ar) {
279 ar.check_end_tag<T>();
280 }
281 }; // struct ArchivePrePostImpl<TextFstreamInputArchive,T>
282
283 /// @}
284 }
285}
286
287#endif // MADNESS_WORLD_TEXT_FSTREAM_ARCHIVE_H__INCLUDED
Interface templates for the archives (serialization).
#define MAD_ARCHIVE_DEBUG(s)
Macro for helping debug archive tools.
Definition archive.h:76
Base class for input archive classes.
Definition archive.h:374
Base class for output archive classes.
Definition archive.h:382
Wraps an archive around a text filestream for input.
Definition text_fstream_archive.h:148
void check_end_tag() const
Read the closing "cookie" tag.
Definition text_fstream_archive.h:199
void close()
Close the filestream.
Definition text_fstream_archive.h:238
void eat_eol() const
Eat the EOL after each entry to enable a char-by-char read of strings.
Definition text_fstream_archive.cc:96
void open(const char *filename, std::ios_base::openmode mode=std::ios_base::in)
Open the filestream.
Definition text_fstream_archive.cc:141
void check_start_tag(bool end=false) const
Check the "cookie" tag in the archive for runtime type-checking.
Definition text_fstream_archive.h:175
TextFstreamInputArchive(const char *filename=nullptr, std::ios_base::openmode mode=std::ios_base::in)
Default constructor.
Definition text_fstream_archive.h:162
std::enable_if< madness::is_istreammable_v< T > >::type load(T *t, long n) const
Load from the filestream.
Definition text_fstream_archive.h:212
std::ifstream is
The filestream.
Definition text_fstream_archive.h:150
Wraps an archive around a text filestream for output.
Definition text_fstream_archive.h:54
std::enable_if< madness::is_ostreammable_v< T > >::type store(const T *t, long n) const
Store data to the filestream.
Definition text_fstream_archive.h:105
void close()
Close the filestream.
Definition text_fstream_archive.cc:87
void store_start_tag() const
Stores the cookie for runtime type-checking into the archive as a tag.
Definition text_fstream_archive.h:75
TextFstreamOutputArchive(const char *filename=nullptr, std::ios_base::openmode mode=std::ios_base::binary|std::ios_base::out|std::ios_base::trunc)
Default constructor.
Definition text_fstream_archive.h:64
~TextFstreamOutputArchive()
Destructor.
Definition text_fstream_archive.h:141
void open(const char *filename, std::ios_base::openmode mode=std::ios_base::out|std::ios_base::trunc)
Open the filestream.
Definition text_fstream_archive.cc:66
std::ofstream os
The filestream.
Definition text_fstream_archive.h:55
void store(const unsigned char *t, long n) const
Store a character string, without escaping characters.
Definition text_fstream_archive.h:120
void flush()
Flush the filestream.
Definition text_fstream_archive.h:135
void store_end_tag() const
Closes the "cookie" tag for runtime type-checking.
Definition text_fstream_archive.h:88
const std::size_t bufsize
Definition derivatives.cc:16
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
const char * archive_type_names[256]
The list of type names for use in archives.
Definition archive_type_names.cc:46
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
static const char * filename
Definition legendre.cc:96
std::string type(const PairType &n)
Definition PNOParameters.h:18
Defines simple templates for printing to std::cout "a la Python".
static void preamble_load(const TextFstreamInputArchive &ar)
Load the preamble and perform type-checking.
Definition text_fstream_archive.h:271
static void postamble_load(const TextFstreamInputArchive &ar)
Load the postamble and perform type-checking.
Definition text_fstream_archive.h:278
static void postamble_store(const TextFstreamOutputArchive &ar)
Write the postamble to the archive.
Definition text_fstream_archive.h:258
static void preamble_store(const TextFstreamOutputArchive &ar)
Write the preamble to the archive.
Definition text_fstream_archive.h:251
Default implementation of the pre/postamble for type checking.
Definition archive.h:509
Used to enable type checking inside archives.
Definition archive.h:115