55#ifndef BITCOIN_FS_H
66#define BITCOIN_FS_H
77
8- #include < stdio.h>
9- #include < string>
10- #if defined WIN32 && defined __GLIBCXX__
11- #include < ext/stdio_filebuf.h>
12- #endif
13-
14- #include < boost/filesystem.hpp>
15- #include < boost/filesystem/fstream.hpp>
168#include < tinyformat.h>
179
10+ #include < cstdio>
11+ #include < filesystem>
12+ #include < iomanip>
13+ #include < ios>
14+ #include < ostream>
15+ #include < string>
16+ #include < utility>
17+
1818/* * Filesystem operations and types */
1919namespace fs {
2020
21- using namespace boost ::filesystem;
21+ using namespace std ::filesystem;
2222
2323/* *
24- * Path class wrapper to prepare application code for transition from
25- * boost::filesystem library to std::filesystem implementation. The main
26- * purpose of the class is to define fs::path::u8string() and fs::u8path()
27- * functions not present in boost. It also blocks calls to the
28- * fs::path(std::string) implicit constructor and the fs::path::string()
29- * method, which worked well in the boost::filesystem implementation, but have
30- * unsafe and unpredictable behavior on Windows in the std::filesystem
31- * implementation (see implementation note in \ref PathToString for details).
24+ * Path class wrapper to block calls to the fs::path(std::string) implicit
25+ * constructor and the fs::path::string() method, which have unsafe and
26+ * unpredictable behavior on Windows (see implementation note in
27+ * \ref PathToString for details)
3228 */
33- class path : public boost ::filesystem::path
29+ class path : public std ::filesystem::path
3430{
3531public:
36- using boost ::filesystem::path::path;
32+ using std ::filesystem::path::path;
3733
3834 // Allow path objects arguments for compatibility.
39- path (boost ::filesystem::path path) : boost ::filesystem::path::path(std::move(path)) {}
40- path& operator =(boost ::filesystem::path path) { boost ::filesystem::path::operator =(std::move (path)); return *this ; }
41- path& operator /=(boost ::filesystem::path path) { boost ::filesystem::path::operator /=(std::move (path)); return *this ; }
35+ path (std ::filesystem::path path) : std ::filesystem::path::path(std::move(path)) {}
36+ path& operator =(std ::filesystem::path path) { std ::filesystem::path::operator =(std::move (path)); return *this ; }
37+ path& operator /=(std ::filesystem::path path) { std ::filesystem::path::operator /=(std::move (path)); return *this ; }
4238
4339 // Allow literal string arguments, which are safe as long as the literals are ASCII.
44- path (const char * c) : boost ::filesystem::path(c) {}
45- path& operator =(const char * c) { boost ::filesystem::path::operator =(c); return *this ; }
46- path& operator /=(const char * c) { boost ::filesystem::path::operator /=(c); return *this ; }
47- path& append (const char * c) { boost ::filesystem::path::append (c); return *this ; }
40+ path (const char * c) : std ::filesystem::path(c) {}
41+ path& operator =(const char * c) { std ::filesystem::path::operator =(c); return *this ; }
42+ path& operator /=(const char * c) { std ::filesystem::path::operator /=(c); return *this ; }
43+ path& append (const char * c) { std ::filesystem::path::append (c); return *this ; }
4844
4945 // Disallow std::string arguments to avoid locale-dependent decoding on windows.
5046 path (std::string) = delete ;
@@ -55,52 +51,48 @@ class path : public boost::filesystem::path
5551 // Disallow std::string conversion method to avoid locale-dependent encoding on windows.
5652 std::string string () const = delete;
5753
58- // Define UTF-8 string conversion method not present in boost::filesystem but present in std::filesystem.
59- std::string u8string () const { return boost::filesystem::path::string (); }
54+ // Required for path overloads in <fstream>.
55+ // See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=96e0367ead5d8dcac3bec2865582e76e2fbab190
56+ path& make_preferred () { std::filesystem::path::make_preferred (); return *this ; }
57+ path filename () const { return std::filesystem::path::filename (); }
6058};
6159
62- // Define UTF-8 string conversion function not present in boost::filesystem but present in std::filesystem.
63- static inline path u8path (const std::string& string)
64- {
65- return boost::filesystem::path (string);
66- }
67-
68- // Disallow implicit std::string conversion for system_complete to avoid
60+ // Disallow implicit std::string conversion for absolute to avoid
6961// locale-dependent encoding on windows.
70- static inline path system_complete (const path& p)
62+ static inline path absolute (const path& p)
7163{
72- return boost ::filesystem::system_complete (p);
64+ return std ::filesystem::absolute (p);
7365}
7466
7567// Disallow implicit std::string conversion for exists to avoid
7668// locale-dependent encoding on windows.
7769static inline bool exists (const path& p)
7870{
79- return boost ::filesystem::exists (p);
71+ return std ::filesystem::exists (p);
8072}
8173
8274// Allow explicit quoted stream I/O.
8375static inline auto quoted (const std::string& s)
8476{
85- return boost::io:: quoted (s, ' &' );
77+ return std:: quoted (s, ' " ' , ' &' );
8678}
8779
8880// Allow safe path append operations.
8981static inline path operator +(path p1, path p2)
9082{
91- p1 += static_cast <boost::filesystem::path&&> (p2);
83+ p1 += std::move (p2);
9284 return p1;
9385}
9486
9587// Disallow implicit std::string conversion for copy_file
9688// to avoid locale-dependent encoding on Windows.
97- static inline void copy_file (const path& from, const path& to, copy_option options)
89+ static inline bool copy_file (const path& from, const path& to, copy_options options)
9890{
99- boost ::filesystem::copy_file (from, to, options);
91+ return std ::filesystem::copy_file (from, to, options);
10092}
10193
10294/* *
103- * Convert path object to byte string. On POSIX, paths natively are byte
95+ * Convert path object to a byte string. On POSIX, paths natively are byte
10496 * strings, so this is trivial. On Windows, paths natively are Unicode, so an
10597 * encoding step is necessary. The inverse of \ref PathToString is \ref
10698 * PathFromString. The strings returned and parsed by these functions can be
@@ -112,7 +104,7 @@ static inline void copy_file(const path& from, const path& to, copy_option optio
112104 * appropriate to use in applications requiring UTF-8, where
113105 * fs::path::u8string() and fs::u8path() methods should be used instead. Other
114106 * applications could require still different encodings. For example, JSON, XML,
115- * or URI applications might prefer to use higher level escapes (\uXXXX or
107+ * or URI applications might prefer to use higher- level escapes (\uXXXX or
116108 * &XXXX; or %XX) instead of multibyte encoding. Rust, Python, Java applications
117109 * may require encoding paths with their respective UTF-8 derivatives WTF-8,
118110 * PEP-383, and CESU-8 (see https://en.wikipedia.org/wiki/UTF-8#Derivatives).
@@ -133,7 +125,7 @@ static inline std::string PathToString(const path& path)
133125 return path.u8string ();
134126#else
135127 static_assert (std::is_same<path::string_type, std::string>::value, " PathToString not implemented on this platform" );
136- return path.boost ::filesystem::path::string ();
128+ return path.std ::filesystem::path::string ();
137129#endif
138130}
139131
@@ -145,7 +137,7 @@ static inline path PathFromString(const std::string& string)
145137#ifdef WIN32
146138 return u8path (string);
147139#else
148- return boost ::filesystem::path (string);
140+ return std ::filesystem::path (string);
149141#endif
150142}
151143} // namespace fs
@@ -186,60 +178,12 @@ namespace fsbridge {
186178 };
187179
188180 std::string get_filesystem_error_message (const fs::filesystem_error& e);
189-
190- // GNU libstdc++ specific workaround for opening UTF-8 paths on Windows.
191- //
192- // On Windows, it is only possible to reliably access multibyte file paths through
193- // `wchar_t` APIs, not `char` APIs. But because the C++ standard doesn't
194- // require ifstream/ofstream `wchar_t` constructors, and the GNU library doesn't
195- // provide them (in contrast to the Microsoft C++ library, see
196- // https://stackoverflow.com/questions/821873/how-to-open-an-stdfstream-ofstream-or-ifstream-with-a-unicode-filename/822032#822032),
197- // Boost is forced to fall back to `char` constructors which may not work properly.
198- //
199- // Work around this issue by creating stream objects with `_wfopen` in
200- // combination with `__gnu_cxx::stdio_filebuf`. This workaround can be removed
201- // with an upgrade to C++17, where streams can be constructed directly from
202- // `std::filesystem::path` objects.
203-
204- #if defined WIN32 && defined __GLIBCXX__
205- class ifstream : public std ::istream
206- {
207- public:
208- ifstream () = default;
209- explicit ifstream (const fs::path& p, std::ios_base::openmode mode = std::ios_base::in) { open (p, mode); }
210- ~ifstream () { close (); }
211- void open (const fs::path& p, std::ios_base::openmode mode = std::ios_base::in);
212- bool is_open () { return m_filebuf.is_open (); }
213- void close ();
214-
215- private:
216- __gnu_cxx::stdio_filebuf<char > m_filebuf;
217- FILE* m_file = nullptr ;
218- };
219- class ofstream : public std ::ostream
220- {
221- public:
222- ofstream () = default ;
223- explicit ofstream (const fs::path& p, std::ios_base::openmode mode = std::ios_base::out) { open (p, mode); }
224- ~ofstream () { close (); }
225- void open (const fs::path& p, std::ios_base::openmode mode = std::ios_base::out);
226- bool is_open () { return m_filebuf.is_open (); }
227- void close ();
228-
229- private:
230- __gnu_cxx::stdio_filebuf<char > m_filebuf;
231- FILE* m_file = nullptr ;
232- };
233- #else // !(WIN32 && __GLIBCXX__)
234- typedef fs::ifstream ifstream;
235- typedef fs::ofstream ofstream;
236- #endif // WIN32 && __GLIBCXX__
237181};
238182
239183// Disallow path operator<< formatting in tinyformat to avoid locale-dependent
240184// encoding on windows.
241185namespace tinyformat {
242- template <> inline void formatValue (std::ostream&, const char *, const char *, int , const boost ::filesystem::path&) = delete;
186+ template <> inline void formatValue (std::ostream&, const char *, const char *, int , const std ::filesystem::path&) = delete;
243187template <> inline void formatValue (std::ostream&, const char *, const char *, int , const fs::path&) = delete;
244188} // namespace tinyformat
245189
0 commit comments