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>
44 #include <madness/world/archive.h>
45 #include <madness/world/print.h> // this injects operator<<(std::ostream,T) for common Ts
46 
47 namespace 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.
142  close();
143  }
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.
251  static void preamble_store(const TextFstreamOutputArchive& ar) {
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
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
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::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
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
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 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
File holds all helper structures necessary for the CC_Operator and CC2 class.
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