1 // path.cpp ----------------------------------------------------------------//
3 // Copyright 2005 Beman Dawes
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 // See library home page at http://www.boost.org/libs/filesystem
10 //----------------------------------------------------------------------------//
12 // define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
13 // the library is being built (possibly exporting rather than importing code)
14 #define BOOST_FILESYSTEM_SOURCE
16 #ifndef BOOST_SYSTEM_NO_DEPRECATED
17 # define BOOST_SYSTEM_NO_DEPRECATED
20 #include <boost/filesystem/v2/config.hpp>
22 #ifndef BOOST_FILESYSTEM2_NARROW_ONLY
24 #include <boost/filesystem/v2/path.hpp>
25 #include <boost/scoped_array.hpp>
28 #include <boost/cerrno.hpp>
29 #include <boost/system/error_code.hpp>
31 #include <cwchar> // for std::mbstate_t
33 #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
34 # include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
40 // std::locale construction can throw (if LC_MESSAGES is wrong, for example),
41 // so a static at function scope is used to ensure that exceptions can be
42 // caught. (A previous version was at namespace scope, so initialization
43 // occurred before main(), preventing exceptions from being caught.)
46 #if !defined(macintosh) && !defined(__APPLE__) && !defined(__APPLE_CC__)
47 // ISO C calls this "the locale-specific native environment":
48 static std::locale
lc("");
50 // "All BSD system functions expect their string parameters to be in UTF-8 encoding
52 // See http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html
53 std::locale global_loc
= std::locale(); // Mac OS doesn't support locale("")
54 static std::locale
lc(global_loc
,
55 new boost::filesystem::detail::utf8_codecvt_facet
);
60 const std::codecvt
<wchar_t, char, std::mbstate_t> *&
63 static const std::codecvt
<wchar_t, char, std::mbstate_t> *
65 &std::use_facet
<std::codecvt
<wchar_t, char, std::mbstate_t> >
71 } // unnamed namespace
77 bool wpath_traits::imbue( const std::locale
& new_loc
, const std::nothrow_t
& )
79 if ( locked
) return false;
82 converter() = &std::use_facet
83 <std::codecvt
<wchar_t, char, std::mbstate_t> >( loc() );
87 void wpath_traits::imbue( const std::locale
& new_loc
)
89 if ( locked
) BOOST_FILESYSTEM_THROW(
91 "boost::filesystem::wpath_traits::imbue() after lockdown",
92 make_error_code( system::errc::not_supported
) ) );
93 imbue( new_loc
, std::nothrow
);
98 // BOOST_FILESYSTEM_DECL
99 // const char * what( const char * sys_err_what,
100 // const path & path1, const path & path2, std::string & target)
104 // if ( target.empty() )
106 // target = sys_err_what;
107 // if ( !path1.empty() )
110 // target += path1.file_string();
113 // if ( !path2.empty() )
116 // target += path2.file_string();
120 // return target.c_str();
124 // return sys_err_what;
129 # ifdef BOOST_POSIX_API
131 // Because this is POSIX only code, we don't have to worry about ABI issues
132 // described in http://www.boost.org/more/separate_compilation.html
134 wpath_traits::external_string_type
135 wpath_traits::to_external( const wpath
& ph
,
136 const internal_string_type
& src
)
139 std::size_t work_size( converter()->max_length() * (src
.size()+1) );
140 boost::scoped_array
<char> work( new char[ work_size
] );
141 std::mbstate_t state
= std::mbstate_t(); // perhaps unneeded, but cuts bug reports
142 const internal_string_type::value_type
* from_next
;
143 external_string_type::value_type
* to_next
;
144 if ( converter()->out(
145 state
, src
.c_str(), src
.c_str()+src
.size(), from_next
, work
.get(),
146 work
.get()+work_size
, to_next
) != std::codecvt_base::ok
)
147 BOOST_FILESYSTEM_THROW( boost::filesystem::wfilesystem_error(
148 "boost::filesystem::wpath::to_external conversion error",
149 ph
, system::error_code( system::errc::invalid_argument
, system::system_category() ) ) );
151 return external_string_type( work
.get() );
154 wpath_traits::internal_string_type
155 wpath_traits::to_internal( const external_string_type
& src
)
158 std::size_t work_size( src
.size()+1 );
159 boost::scoped_array
<wchar_t> work( new wchar_t[ work_size
] );
160 std::mbstate_t state
= std::mbstate_t(); // perhaps unneeded, but cuts bug reports
161 const external_string_type::value_type
* from_next
;
162 internal_string_type::value_type
* to_next
;
163 if ( converter()->in(
164 state
, src
.c_str(), src
.c_str()+src
.size(), from_next
, work
.get(),
165 work
.get()+work_size
, to_next
) != std::codecvt_base::ok
)
166 BOOST_FILESYSTEM_THROW( boost::filesystem::wfilesystem_error(
167 "boost::filesystem::wpath::to_internal conversion error",
168 system::error_code( system::errc::invalid_argument
, system::system_category() ) ) );
170 return internal_string_type( work
.get() );
172 # endif // BOOST_POSIX_API
174 } // namespace filesystem2
177 #endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY