@@ -113,4 +113,106 @@ std::string get_filesystem_error_message(const fs::filesystem_error& e)
113
113
#endif
114
114
}
115
115
116
+ #ifdef WIN32
117
+ #ifdef __GLIBCXX__
118
+
119
+ // reference: https://github.com/gcc-mirror/gcc/blob/gcc-7_3_0-release/libstdc%2B%2B-v3/include/std/fstream#L270
120
+
121
+ static std::string openmodeToStr (std::ios_base::openmode mode)
122
+ {
123
+ switch (mode & ~std::ios_base::ate) {
124
+ case std::ios_base::out:
125
+ case std::ios_base::out | std::ios_base::trunc:
126
+ return " w" ;
127
+ case std::ios_base::out | std::ios_base::app:
128
+ case std::ios_base::app:
129
+ return " a" ;
130
+ case std::ios_base::in:
131
+ return " r" ;
132
+ case std::ios_base::in | std::ios_base::out:
133
+ return " r+" ;
134
+ case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
135
+ return " w+" ;
136
+ case std::ios_base::in | std::ios_base::out | std::ios_base::app:
137
+ case std::ios_base::in | std::ios_base::app:
138
+ return " a+" ;
139
+ case std::ios_base::out | std::ios_base::binary:
140
+ case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
141
+ return " wb" ;
142
+ case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
143
+ case std::ios_base::app | std::ios_base::binary:
144
+ return " ab" ;
145
+ case std::ios_base::in | std::ios_base::binary:
146
+ return " rb" ;
147
+ case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
148
+ return " r+b" ;
149
+ case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
150
+ return " w+b" ;
151
+ case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
152
+ case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
153
+ return " a+b" ;
154
+ default :
155
+ return std::string ();
156
+ }
157
+ }
158
+
159
+ void ifstream::open (const fs::path& p, std::ios_base::openmode mode)
160
+ {
161
+ close ();
162
+ m_file = fsbridge::fopen (p, openmodeToStr (mode).c_str ());
163
+ if (m_file == nullptr ) {
164
+ return ;
165
+ }
166
+ m_filebuf = __gnu_cxx::stdio_filebuf<char >(m_file, mode);
167
+ rdbuf (&m_filebuf);
168
+ if (mode & std::ios_base::ate) {
169
+ seekg (0 , std::ios_base::end);
170
+ }
171
+ }
172
+
173
+ void ifstream::close ()
174
+ {
175
+ if (m_file != nullptr ) {
176
+ m_filebuf.close ();
177
+ fclose (m_file);
178
+ }
179
+ m_file = nullptr ;
180
+ }
181
+
182
+ void ofstream::open (const fs::path& p, std::ios_base::openmode mode)
183
+ {
184
+ close ();
185
+ m_file = fsbridge::fopen (p, openmodeToStr (mode).c_str ());
186
+ if (m_file == nullptr ) {
187
+ return ;
188
+ }
189
+ m_filebuf = __gnu_cxx::stdio_filebuf<char >(m_file, mode);
190
+ rdbuf (&m_filebuf);
191
+ if (mode & std::ios_base::ate) {
192
+ seekp (0 , std::ios_base::end);
193
+ }
194
+ }
195
+
196
+ void ofstream::close ()
197
+ {
198
+ if (m_file != nullptr ) {
199
+ m_filebuf.close ();
200
+ fclose (m_file);
201
+ }
202
+ m_file = nullptr ;
203
+ }
204
+ #else // __GLIBCXX__
205
+
206
+ static_assert (sizeof (*fs::path ().BOOST_FILESYSTEM_C_STR) == sizeof(wchar_t ),
207
+ "Warning: This build is using boost::filesystem ofstream and ifstream "
208
+ "implementations which will fail to open paths containing multibyte "
209
+ "characters. You should delete this static_assert to ignore this warning, "
210
+ "or switch to a different C++ standard library like the Microsoft C++ "
211
+ "Standard Library (where boost uses non-standard extensions to construct "
212
+ " stream objects with wide filenames), or the GNU libstdc++ library (where "
213
+ " a more complicated workaround has been implemented above).");
214
+
215
+ #endif // __GLIBCXX__
216
+ #endif // WIN32
217
+
116
218
} // fsbridge
0 commit comments