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 /*
2  Copyright 2008 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 
32 /// @file fstream_mingw.h
33 ///
34 /// @brief Utilities for dealing with fstream on MingW.
35 /// Basically accepting wchar_t* filenames in the std::ifstream::open function
36 /// is a Windows MSVC extension and does not work on MingW. This file implements
37 /// ifstream and ofstream so that they work with UTF-16 filenames.
38 
39 
40 #pragma once
41 
42 #include <cassert>
43 #include <istream>
44 #include <ostream>
45 
46 #if defined(_WIN32) && defined(__GLIBCXX__)
47 # include <Share.h>
48 # include <ext/stdio_filebuf.h> // __gnu_cxx::stdio_filebuf
49 # include <fcntl.h>
50 # include <sys/stat.h>
51 
52 
54 
55 
56 template<class _CharT, class _Traits = std::char_traits<_CharT>>
57 class basic_ifstream : public std::basic_istream<_CharT, _Traits> {
58 public:
59  typedef _CharT char_type;
60  typedef _Traits traits_type;
61  typedef typename traits_type::int_type int_type;
62  typedef typename traits_type::pos_type pos_type;
63  typedef typename traits_type::off_type off_type;
64 
65  typedef typename __gnu_cxx::stdio_filebuf<char_type, traits_type>
66  stdio_filebuf;
67 
68 
69  basic_ifstream();
70  explicit basic_ifstream(const std::wstring& path,
71  std::ios_base::openmode __mode = std::ios_base::in);
72 
73  virtual ~basic_ifstream();
74 
75  stdio_filebuf* rdbuf() const;
76  bool is_open() const;
77  void open(const std::wstring& path,
78  std::ios_base::openmode __mode = std::ios_base::in);
79  void close();
80 
81 private:
82  void open_internal(const std::wstring& path, std::ios_base::openmode mode);
83 
84  stdio_filebuf* __sb_;
85 };
86 
87 template<class _CharT, class _Traits>
88 inline basic_ifstream<_CharT, _Traits>::basic_ifstream()
89  : std::basic_istream<char_type, traits_type>(0)
90  , __sb_(0)
91 {
92 }
93 
94 
95 template<class _CharT, class _Traits>
96 inline basic_ifstream<_CharT, _Traits>::basic_ifstream(
97  const std::wstring& path, std::ios_base::openmode __mode)
98  : std::basic_istream<char_type, traits_type>(0)
99  , __sb_(0)
100 {
101  open_internal(path, __mode | std::ios_base::in);
102 }
103 
104 template<class _CharT, class _Traits>
105 inline basic_ifstream<_CharT, _Traits>::~basic_ifstream()
106 {
107  delete __sb_;
108 }
109 
110 
111 inline int
112 ios_open_mode_to_oflag(std::ios_base::openmode mode)
113 {
114  int f = 0;
115  if (mode & std::ios_base::in) {
116  f |= _O_RDONLY;
117  }
118  if (mode & std::ios_base::out) {
119  f |= _O_WRONLY;
120  f |= _O_CREAT;
121  if (mode & std::ios_base::app) {
122  f |= _O_APPEND;
123  }
124  if (mode & std::ios_base::trunc) {
125  f |= _O_TRUNC;
126  }
127  }
128  if (mode & std::ios_base::binary) {
129  f |= _O_BINARY;
130  } else {
131  f |= _O_TEXT;
132  }
133  return f;
134 }
135 
136 template<class _CharT, class _Traits>
137 inline void
138 basic_ifstream<_CharT, _Traits>::open_internal(const std::wstring& path,
139  std::ios_base::openmode mode)
140 {
141  if (is_open()) {
142  // if the stream is already associated with a file (i.e., it is already open), calling this function fails.
143  this->setstate(std::ios_base::failbit);
144  return;
145  }
146  int fd;
147  int oflag = ios_open_mode_to_oflag(mode);
148  errno_t errcode = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO,
149  _S_IREAD | _S_IWRITE);
150  if (errcode != 0) {
151  this->setstate(std::ios_base::failbit);
152  return;
153  }
154  __sb_ = new stdio_filebuf(fd, mode, 1);
155  if (__sb_ == 0) {
156  this->setstate(std::ios_base::failbit);
157  return;
158  }
159  // 409. Closing an fstream should clear error state
160  this->clear();
161  assert(__sb_);
162 
163  // In init() the rdstate() is set to badbit if __sb_ is NULL and
164  // goodbit otherwise. The assert afterwards ensures this.
165  this->init(__sb_);
166  assert(this->good() && !this->fail());
167 }
168 
169 template<class _CharT, class _Traits>
170 inline typename basic_ifstream<_CharT, _Traits>::stdio_filebuf*
171 basic_ifstream<_CharT, _Traits>::rdbuf() const
172 {
173  return const_cast<stdio_filebuf*>(__sb_);
174 }
175 
176 
177 template<class _CharT, class _Traits>
178 inline bool
179 basic_ifstream<_CharT, _Traits>::is_open() const
180 {
181  return __sb_ && __sb_->is_open();
182 }
183 
184 
185 template<class _CharT, class _Traits>
186 void
187 basic_ifstream<_CharT, _Traits>::open(const std::wstring& path,
188  std::ios_base::openmode __mode)
189 {
190  open_internal(path, __mode | std::ios_base::in);
191 }
192 
193 template<class _CharT, class _Traits>
194 inline void
196 {
197  if (!__sb_) {
198  return;
199  }
200  if (__sb_->close() == 0)
201  this->setstate(std::ios_base::failbit);
202 
203  delete __sb_;
204  __sb_ = 0;
205 }
206 
207 
208 
209 template<class _CharT, class _Traits = std::char_traits<_CharT>>
210 class basic_ofstream : public std::basic_ostream<_CharT, _Traits> {
211 public:
212  typedef _CharT char_type;
213  typedef _Traits traits_type;
214  typedef typename traits_type::int_type int_type;
215  typedef typename traits_type::pos_type pos_type;
216  typedef typename traits_type::off_type off_type;
217 
218  typedef typename __gnu_cxx::stdio_filebuf<char_type, traits_type>
219  stdio_filebuf;
220 
221 
222  basic_ofstream();
223  explicit basic_ofstream(const std::wstring& path,
224  std::ios_base::openmode __mode = std::ios_base::out);
225 
226  virtual ~basic_ofstream();
227 
228  stdio_filebuf* rdbuf() const;
229  bool is_open() const;
230  void open(const std::wstring& path,
231  std::ios_base::openmode __mode = std::ios_base::out);
232  void close();
233 
234 private:
235  void open_internal(const std::wstring& path, std::ios_base::openmode mode);
236 
237  stdio_filebuf* __sb_;
238 };
239 
240 template<class _CharT, class _Traits>
241 inline basic_ofstream<_CharT, _Traits>::basic_ofstream()
242  : std::basic_ostream<char_type, traits_type>(0)
243  , __sb_(0)
244 {
245 }
246 
247 
248 template<class _CharT, class _Traits>
249 inline basic_ofstream<_CharT, _Traits>::basic_ofstream(
250  const std::wstring& path, std::ios_base::openmode __mode)
251  : std::basic_ostream<char_type, traits_type>(0)
252  , __sb_(0)
253 {
254  open_internal(path, __mode | std::ios_base::out);
255 }
256 
257 template<class _CharT, class _Traits>
258 inline basic_ofstream<_CharT, _Traits>::~basic_ofstream()
259 {
260  delete __sb_;
261 }
262 
263 
264 template<class _CharT, class _Traits>
265 inline void
266 basic_ofstream<_CharT, _Traits>::open_internal(const std::wstring& path,
267  std::ios_base::openmode mode)
268 {
269  if (is_open()) {
270  // if the stream is already associated with a file (i.e., it is already open), calling this function fails.
271  this->setstate(std::ios_base::failbit);
272  return;
273  }
274  int fd;
275  int oflag = ios_open_mode_to_oflag(mode);
276  errno_t errcode = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO,
277  _S_IREAD | _S_IWRITE);
278  if (errcode != 0) {
279  this->setstate(std::ios_base::failbit);
280  return;
281  }
282  __sb_ = new stdio_filebuf(fd, mode, 1);
283  if (__sb_ == 0) {
284  this->setstate(std::ios_base::failbit);
285  return;
286  }
287  // 409. Closing an fstream should clear error state
288  this->clear();
289  assert(__sb_);
290 
291  // In init() the rdstate() is set to badbit if __sb_ is NULL and
292  // goodbit otherwise. The assert afterwards ensures this.
293  this->init(__sb_);
294  assert(this->good() && !this->fail());
295 }
296 
297 
298 template<class _CharT, class _Traits>
299 inline typename basic_ofstream<_CharT, _Traits>::stdio_filebuf*
300 basic_ofstream<_CharT, _Traits>::rdbuf() const
301 {
302  return const_cast<stdio_filebuf*>(__sb_);
303 }
304 
305 
306 
307 template<class _CharT, class _Traits>
308 inline bool
309 basic_ofstream<_CharT, _Traits>::is_open() const
310 {
311  return __sb_ && __sb_->is_open();
312 }
313 
314 
315 template<class _CharT, class _Traits>
316 void
317 basic_ofstream<_CharT, _Traits>::open(const std::wstring& path,
318  std::ios_base::openmode __mode)
319 {
320  open_internal(path, __mode | std::ios_base::out);
321 }
322 
323 template<class _CharT, class _Traits>
324 inline void
326 {
327  if (!__sb_) {
328  return;
329  }
330  if (__sb_->close() == 0)
331  this->setstate(std::ios_base::failbit);
332 
333  delete __sb_;
334  __sb_ = 0;
335 }
336 // basic_fstream
337 
339 
340 
341 #endif // #if defined(_WIN32) && defined(__GLIBCXX__)
GLenum mode
Definition: glew.h:2163
int trunc(T x)
Definition: ImathFun.h:165
GLclampf f
Definition: glew.h:3499
GLuint in
Definition: glew.h:11510
const GLuint GLenum const void * binary
Definition: glew.h:3502
virtual int open(float queuesize)
GLsizei const GLchar *const * path
Definition: glew.h:6461
virtual void close()
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:65