@@ -113,4 +113,106 @@ std::string get_filesystem_error_message(const fs::filesystem_error& e)
113113#endif
114114}
115115
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+
116218} // fsbridge
0 commit comments