Eclipse SUMO - Simulation of Urban MObility
strict_fstream.hpp
Go to the documentation of this file.
1 #ifndef __STRICT_FSTREAM_HPP
2 #define __STRICT_FSTREAM_HPP
3 
4 #define __STDC_WANT_LIB_EXT1__ 1
5 #include <cassert>
6 #include <fstream>
7 #include <cstring>
8 #include <string>
9 
10 #ifndef _MSC_VER
11 #define NOEXCEPT noexcept
12 #else
13 #define NOEXCEPT
14 #endif
15 
24 namespace strict_fstream
25 {
26 
29 static std::string strerror()
30 {
31  std::string buff(80, '\0');
32 #if defined _WIN32 || defined __STDC_LIB_EXT1__
33  if (strerror_s(&buff[0], buff.size(), errno) != 0)
34  {
35  buff = "Unknown error";
36  }
37 #else
38  if (strerror_r(errno, &buff[0], buff.size()) != 0)
39  {
40  buff = "Unknown error";
41  }
42 #endif
43  buff.resize(buff.find('\0'));
44  return buff;
45 }
46 
48 class Exception
49  : public std::exception
50 {
51 public:
52  Exception(const std::string& msg) : _msg(msg) {}
53  const char * what() const NOEXCEPT { return _msg.c_str(); }
54 private:
55  std::string _msg;
56 }; // class Exception
57 
58 namespace detail
59 {
60 
62 {
63  static std::string mode_to_string(std::ios_base::openmode mode)
64  {
65  static const int n_modes = 6;
66  static const std::ios_base::openmode mode_val_v[n_modes] =
67  {
68  std::ios_base::in,
69  std::ios_base::out,
70  std::ios_base::app,
71  std::ios_base::ate,
72  std::ios_base::trunc,
73  std::ios_base::binary
74  };
75 
76  static const char * mode_name_v[n_modes] =
77  {
78  "in",
79  "out",
80  "app",
81  "ate",
82  "trunc",
83  "binary"
84  };
85  std::string res;
86  for (int i = 0; i < n_modes; ++i)
87  {
88  if (mode & mode_val_v[i])
89  {
90  res += (! res.empty()? "|" : "");
91  res += mode_name_v[i];
92  }
93  }
94  if (res.empty()) res = "none";
95  return res;
96  }
97  static void check_mode(const std::string& filename, std::ios_base::openmode mode)
98  {
99  if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out))
100  {
101  throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: trunc and not out");
102  }
103  else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out))
104  {
105  throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: app and not out");
106  }
107  else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app))
108  {
109  throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: trunc and app");
110  }
111  }
112  static void check_open(std::ios * s_p, const std::string& filename, std::ios_base::openmode mode)
113  {
114  if (s_p->fail())
115  {
116  throw Exception(std::string("strict_fstream: open('")
117  + filename + "'," + mode_to_string(mode) + "): open failed: "
118  + strerror());
119  }
120  }
121  static void check_peek(std::istream * is_p, const std::string& filename, std::ios_base::openmode mode)
122  {
123  bool peek_failed = true;
124  try
125  {
126  is_p->peek();
127  peek_failed = is_p->fail();
128  }
129  catch (std::ios_base::failure&) {}
130  if (peek_failed)
131  {
132  throw Exception(std::string("strict_fstream: open('")
133  + filename + "'," + mode_to_string(mode) + "): peek failed: "
134  + strerror());
135  }
136  is_p->clear();
137  }
138 }; // struct static_method_holder
139 
140 } // namespace detail
141 
142 class ifstream
143  : public std::ifstream
144 {
145 public:
146  ifstream() = default;
147  ifstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
148  {
149  open(filename, mode);
150  }
151  void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
152  {
153  mode |= std::ios_base::in;
154  exceptions(std::ios_base::badbit);
156  std::ifstream::open(filename, mode);
157  detail::static_method_holder::check_open(this, filename, mode);
158  detail::static_method_holder::check_peek(this, filename, mode);
159  }
160 }; // class ifstream
161 
162 class ofstream
163  : public std::ofstream
164 {
165 public:
166  ofstream() = default;
167  ofstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
168  {
169  open(filename, mode);
170  }
171  void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
172  {
173  mode |= std::ios_base::out;
174  exceptions(std::ios_base::badbit);
176  std::ofstream::open(filename, mode);
177  detail::static_method_holder::check_open(this, filename, mode);
178  }
179 }; // class ofstream
180 
181 class fstream
182  : public std::fstream
183 {
184 public:
185  fstream() = default;
186  fstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
187  {
188  open(filename, mode);
189  }
190  void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
191  {
192  if (! (mode & std::ios_base::out)) mode |= std::ios_base::in;
193  exceptions(std::ios_base::badbit);
195  std::fstream::open(filename, mode);
196  detail::static_method_holder::check_open(this, filename, mode);
197  detail::static_method_holder::check_peek(this, filename, mode);
198  }
199 }; // class fstream
200 
201 } // namespace strict_fstream
202 
203 #endif
Exception class thrown by failed operations.
Exception(const std::string &msg)
const char * what() const NOEXCEPT
fstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
static std::string strerror()
#define NOEXCEPT
static void check_mode(const std::string &filename, std::ios_base::openmode mode)
static void check_open(std::ios *s_p, const std::string &filename, std::ios_base::openmode mode)
static std::string mode_to_string(std::ios_base::openmode mode)
static void check_peek(std::istream *is_p, const std::string &filename, std::ios_base::openmode mode)