1 // Boost.Filesystem mbpath.cpp ---------------------------------------------// 2 3 // (c) Copyright Beman Dawes 2005 4 5 // Use, modification, and distribution is subject to the Boost Software 6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 // See Boost.Filesystem home page at http://www.boost.org/libs/filesystem 10 11 #include <boost/filesystem/config.hpp> 12 # ifdef BOOST_FILESYSTEM_NARROW_ONLY 13 # error This compiler or standard library does not support wide-character strings or paths 14 # endif 15 16 #include "mbpath.hpp" 17 #include <boost/system/system_error.hpp> 18 #include <boost/scoped_array.hpp> 19 20 namespace fs = boost::filesystem; 21 22 namespace 23 { 24 // ISO C calls this "the locale-specific native environment": 25 std::locale loc(""); 26 27 const std::codecvt<wchar_t, char, std::mbstate_t> * 28 cvt( &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > 29 ( loc ) ); 30 } 31 32 namespace user 33 { 34 mbpath_traits::external_string_type to_external(const mbpath & ph,const internal_string_type & src)35 mbpath_traits::to_external( const mbpath & ph, 36 const internal_string_type & src ) 37 { 38 std::size_t work_size( cvt->max_length() * (src.size()+1) ); 39 boost::scoped_array<char> work( new char[ work_size ] ); 40 std::mbstate_t state; 41 const internal_string_type::value_type * from_next; 42 external_string_type::value_type * to_next; 43 if ( cvt->out( 44 state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), 45 work.get()+work_size, to_next ) != std::codecvt_base::ok ) 46 boost::throw_exception<fs::basic_filesystem_error<mbpath> >( 47 fs::basic_filesystem_error<mbpath>( 48 "user::mbpath::to_external conversion error", 49 ph, boost::system::error_code( EINVAL, boost::system::errno_ecat ) ) ); 50 *to_next = '\0'; 51 return external_string_type( work.get() ); 52 } 53 54 mbpath_traits::internal_string_type to_internal(const external_string_type & src)55 mbpath_traits::to_internal( const external_string_type & src ) 56 { 57 std::size_t work_size( src.size()+1 ); 58 boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] ); 59 std::mbstate_t state; 60 const external_string_type::value_type * from_next; 61 internal_string_type::value_type * to_next; 62 if ( cvt->in( 63 state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), 64 work.get()+work_size, to_next ) != std::codecvt_base::ok ) 65 boost::throw_exception<fs::basic_filesystem_error<mbpath> >( 66 fs::basic_filesystem_error<mbpath>( 67 "user::mbpath::to_internal conversion error", 68 boost::system::error_code( EINVAL, boost::system::errno_ecat ) ) ); 69 *to_next = L'\0'; 70 return internal_string_type( work.get() ); 71 } 72 imbue(const std::locale & new_loc)73 void mbpath_traits::imbue( const std::locale & new_loc ) 74 { 75 loc = new_loc; 76 cvt = &std::use_facet 77 <std::codecvt<wchar_t, char, std::mbstate_t> >( loc ); 78 } 79 80 } // namespace user 81