HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fstream_mingw.h
Go to the documentation of this file.
1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio
4 
5 
6 /// @file fstream_mingw.h
7 ///
8 /// @brief Utilities for dealing with fstream on MingW.
9 /// Basically accepting wchar_t* filenames in the std::ifstream::open function
10 /// is a Windows MSVC extension and does not work on MingW. This file implements
11 /// ifstream and ofstream so that they work with UTF-16 filenames.
12 
13 
14 #pragma once
15 
16 #include <cassert>
17 #include <istream>
18 #include <ostream>
19 
20 #if defined(_WIN32) && defined(__GLIBCXX__)
21 # include <ext/stdio_filebuf.h> // __gnu_cxx::stdio_filebuf
22 # include <fcntl.h>
23 # include <share.h>
24 # include <sys/stat.h>
25 
26 
28 
29 
30 template<class _CharT, class _Traits = std::char_traits<_CharT>>
31 class basic_ifstream : public std::basic_istream<_CharT, _Traits> {
32 public:
33  typedef _CharT char_type;
34  typedef _Traits traits_type;
35  typedef typename traits_type::int_type int_type;
36  typedef typename traits_type::pos_type pos_type;
37  typedef typename traits_type::off_type off_type;
38 
39  typedef typename __gnu_cxx::stdio_filebuf<char_type, traits_type>
40  stdio_filebuf;
41 
42 
43  basic_ifstream();
44  explicit basic_ifstream(const std::wstring& path,
45  std::ios_base::openmode __mode = std::ios_base::in);
46 
47  virtual ~basic_ifstream();
48 
49  stdio_filebuf* rdbuf() const;
50  bool is_open() const;
51  void open(const std::wstring& path,
52  std::ios_base::openmode __mode = std::ios_base::in);
53  void close();
54 
55 private:
56  void open_internal(const std::wstring& path, std::ios_base::openmode mode);
57 
58  stdio_filebuf* __sb_;
59 };
60 
61 template<class _CharT, class _Traits>
62 inline basic_ifstream<_CharT, _Traits>::basic_ifstream()
63  : std::basic_istream<char_type, traits_type>(0)
64  , __sb_(0)
65 {
66 }
67 
68 
69 template<class _CharT, class _Traits>
70 inline basic_ifstream<_CharT, _Traits>::basic_ifstream(
71  const std::wstring& path, std::ios_base::openmode __mode)
72  : std::basic_istream<char_type, traits_type>(0)
73  , __sb_(0)
74 {
75  open_internal(path, __mode | std::ios_base::in);
76 }
77 
78 template<class _CharT, class _Traits>
79 inline basic_ifstream<_CharT, _Traits>::~basic_ifstream()
80 {
81  delete __sb_;
82 }
83 
84 
85 inline int
86 ios_open_mode_to_oflag(std::ios_base::openmode mode)
87 {
88  int f = 0;
89  if (mode & std::ios_base::in) {
90  f |= _O_RDONLY;
91  }
92  if (mode & std::ios_base::out) {
93  f |= _O_WRONLY;
94  f |= _O_CREAT;
95  if (mode & std::ios_base::app) {
96  f |= _O_APPEND;
97  }
98  if (mode & std::ios_base::trunc) {
99  f |= _O_TRUNC;
100  }
101  }
102  if (mode & std::ios_base::binary) {
103  f |= _O_BINARY;
104  } else {
105  f |= _O_TEXT;
106  }
107  return f;
108 }
109 
110 template<class _CharT, class _Traits>
111 inline void
112 basic_ifstream<_CharT, _Traits>::open_internal(const std::wstring& path,
113  std::ios_base::openmode mode)
114 {
115  if (is_open()) {
116  // if the stream is already associated with a file (i.e., it is already open), calling this function fails.
117  this->setstate(std::ios_base::failbit);
118  return;
119  }
120  int fd;
121  int oflag = ios_open_mode_to_oflag(mode);
122  errno_t errcode = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO,
123  _S_IREAD | _S_IWRITE);
124  if (errcode != 0) {
125  this->setstate(std::ios_base::failbit);
126  return;
127  }
128  __sb_ = new stdio_filebuf(fd, mode, 1);
129  if (__sb_ == 0) {
130  this->setstate(std::ios_base::failbit);
131  return;
132  }
133  // 409. Closing an fstream should clear error state
134  this->clear();
135  assert(__sb_);
136 
137  // In init() the rdstate() is set to badbit if __sb_ is NULL and
138  // goodbit otherwise. The assert afterwards ensures this.
139  this->init(__sb_);
140  assert(this->good() && !this->fail());
141 }
142 
143 template<class _CharT, class _Traits>
144 inline typename basic_ifstream<_CharT, _Traits>::stdio_filebuf*
145 basic_ifstream<_CharT, _Traits>::rdbuf() const
146 {
147  return const_cast<stdio_filebuf*>(__sb_);
148 }
149 
150 
151 template<class _CharT, class _Traits>
152 inline bool
153 basic_ifstream<_CharT, _Traits>::is_open() const
154 {
155  return __sb_ && __sb_->is_open();
156 }
157 
158 
159 template<class _CharT, class _Traits>
160 void
161 basic_ifstream<_CharT, _Traits>::open(const std::wstring& path,
162  std::ios_base::openmode __mode)
163 {
164  open_internal(path, __mode | std::ios_base::in);
165 }
166 
167 template<class _CharT, class _Traits>
168 inline void
170 {
171  if (!__sb_) {
172  return;
173  }
174  if (__sb_->close() == 0)
175  this->setstate(std::ios_base::failbit);
176 
177  delete __sb_;
178  __sb_ = 0;
179 }
180 
181 
182 
183 template<class _CharT, class _Traits = std::char_traits<_CharT>>
184 class basic_ofstream : public std::basic_ostream<_CharT, _Traits> {
185 public:
186  typedef _CharT char_type;
187  typedef _Traits traits_type;
188  typedef typename traits_type::int_type int_type;
189  typedef typename traits_type::pos_type pos_type;
190  typedef typename traits_type::off_type off_type;
191 
192  typedef typename __gnu_cxx::stdio_filebuf<char_type, traits_type>
193  stdio_filebuf;
194 
195 
196  basic_ofstream();
197  explicit basic_ofstream(const std::wstring& path,
198  std::ios_base::openmode __mode = std::ios_base::out);
199 
200  virtual ~basic_ofstream();
201 
202  stdio_filebuf* rdbuf() const;
203  bool is_open() const;
204  void open(const std::wstring& path,
205  std::ios_base::openmode __mode = std::ios_base::out);
206  void close();
207 
208 private:
209  void open_internal(const std::wstring& path, std::ios_base::openmode mode);
210 
211  stdio_filebuf* __sb_;
212 };
213 
214 template<class _CharT, class _Traits>
215 inline basic_ofstream<_CharT, _Traits>::basic_ofstream()
216  : std::basic_ostream<char_type, traits_type>(0)
217  , __sb_(0)
218 {
219 }
220 
221 
222 template<class _CharT, class _Traits>
223 inline basic_ofstream<_CharT, _Traits>::basic_ofstream(
224  const std::wstring& path, std::ios_base::openmode __mode)
225  : std::basic_ostream<char_type, traits_type>(0)
226  , __sb_(0)
227 {
228  open_internal(path, __mode | std::ios_base::out);
229 }
230 
231 template<class _CharT, class _Traits>
232 inline basic_ofstream<_CharT, _Traits>::~basic_ofstream()
233 {
234  delete __sb_;
235 }
236 
237 
238 template<class _CharT, class _Traits>
239 inline void
240 basic_ofstream<_CharT, _Traits>::open_internal(const std::wstring& path,
241  std::ios_base::openmode mode)
242 {
243  if (is_open()) {
244  // if the stream is already associated with a file (i.e., it is already open), calling this function fails.
245  this->setstate(std::ios_base::failbit);
246  return;
247  }
248  int fd;
249  int oflag = ios_open_mode_to_oflag(mode);
250  errno_t errcode = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO,
251  _S_IREAD | _S_IWRITE);
252  if (errcode != 0) {
253  this->setstate(std::ios_base::failbit);
254  return;
255  }
256  __sb_ = new stdio_filebuf(fd, mode, 1);
257  if (__sb_ == 0) {
258  this->setstate(std::ios_base::failbit);
259  return;
260  }
261  // 409. Closing an fstream should clear error state
262  this->clear();
263  assert(__sb_);
264 
265  // In init() the rdstate() is set to badbit if __sb_ is NULL and
266  // goodbit otherwise. The assert afterwards ensures this.
267  this->init(__sb_);
268  assert(this->good() && !this->fail());
269 }
270 
271 
272 template<class _CharT, class _Traits>
273 inline typename basic_ofstream<_CharT, _Traits>::stdio_filebuf*
274 basic_ofstream<_CharT, _Traits>::rdbuf() const
275 {
276  return const_cast<stdio_filebuf*>(__sb_);
277 }
278 
279 
280 
281 template<class _CharT, class _Traits>
282 inline bool
283 basic_ofstream<_CharT, _Traits>::is_open() const
284 {
285  return __sb_ && __sb_->is_open();
286 }
287 
288 
289 template<class _CharT, class _Traits>
290 void
291 basic_ofstream<_CharT, _Traits>::open(const std::wstring& path,
292  std::ios_base::openmode __mode)
293 {
294  open_internal(path, __mode | std::ios_base::out);
295 }
296 
297 template<class _CharT, class _Traits>
298 inline void
300 {
301  if (!__sb_) {
302  return;
303  }
304  if (__sb_->close() == 0)
305  this->setstate(std::ios_base::failbit);
306 
307  delete __sb_;
308  __sb_ = 0;
309 }
310 // basic_fstream
311 
313 
314 
315 #endif // #if defined(_WIN32) && defined(__GLIBCXX__)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
void close() override
GLfloat f
Definition: glcorearb.h:1926
IMATH_HOSTDEVICE constexpr int trunc(T x) IMATH_NOEXCEPT
Definition: ImathFun.h:126
int open(float queuesize) override
GLenum mode
Definition: glcorearb.h:99
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
GLuint64 GLenum GLint fd
Definition: RE_OGL.h:262
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93