// Boost wide_test.cpp -----------------------------------------------------// // Copyright Beman Dawes 2005 // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See library home page at http://www.boost.org/libs/filesystem #include // See deprecated_test for tests of deprecated features #ifndef BOOST_FILESYSTEM_NO_DEPRECATED # define BOOST_FILESYSTEM_NO_DEPRECATED #endif #ifndef BOOST_SYSTEM_NO_DEPRECATED # define BOOST_SYSTEM_NO_DEPRECATED #endif #include # ifdef BOOST_FILESYSTEM2_NARROW_ONLY # error This compiler or standard library does not support wide-character strings or paths # endif #include #include #include #include #include namespace fs = boost::filesystem; #include #include #include #include #include #include "lpath.hpp" namespace { bool cleanup = true; template< class Path > void create_file( const Path & ph, const std::string & contents ) { // TODO: why missing symbol error on Darwin # ifndef __APPLE__ fs::ofstream f( ph ); # else std::ofstream f( ph.external_file_string().c_str() ); # endif if ( !f ) throw fs::basic_filesystem_error( "wide_test create_file", ph, boost::system::error_code( errno, boost::system::generic_category() ) ); if ( !contents.empty() ) f << contents; } template< class Path > void test( const Path & dir, const Path & file, const Path & dot ) { Path tmp; tmp = file; BOOST_TEST( tmp == file ); tmp = file.string(); BOOST_TEST( tmp == file ); tmp = file.string().c_str(); BOOST_TEST( tmp == file ); fs::initial_path(); fs::current_path(); fs::remove( dir / file ); fs::remove( dir ); BOOST_TEST( !fs::exists( dir / file ) ); BOOST_TEST( !fs::exists( dir ) ); BOOST_TEST( fs::create_directory( dir ) ); BOOST_TEST( fs::exists( dir ) ); BOOST_TEST( fs::is_directory( dir ) ); BOOST_TEST( fs::is_empty( dir ) ); create_file( dir / file, "wide_test file contents" ); BOOST_TEST( fs::exists( dir / file ) ); BOOST_TEST( !fs::is_directory( dir / file ) ); BOOST_TEST( !fs::is_empty( dir / file ) ); BOOST_TEST( fs::file_size( dir / file ) == 23 || fs::file_size( dir / file ) == 24 ); BOOST_TEST( fs::equivalent( dir / file, dot / dir / file ) ); BOOST_TEST( fs::last_write_time( dir / file ) ); typedef fs::basic_directory_iterator it_t; int count(0); for ( it_t it( dir ); it != it_t(); ++it ) { BOOST_TEST( it->path() == dir / file ); BOOST_TEST( !fs::is_empty( it->path() ) ); ++count; } BOOST_TEST( count == 1 ); if ( cleanup ) { fs::remove( dir / file ); fs::remove( dir ); } } // test boost::detail::utf8_codecvt_facet - even though it is not used by // Boost.Filesystem on Windows, early detection of problems is worthwhile. std::string to_external( const std::wstring & src ) { fs::detail::utf8_codecvt_facet convertor; std::size_t work_size( convertor.max_length() * (src.size()+1) ); boost::scoped_array work( new char[ work_size ] ); std::mbstate_t state; const wchar_t * from_next; char * to_next; if ( convertor.out( state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), work.get()+work_size, to_next ) != std::codecvt_base::ok ) boost::throw_exception( std::runtime_error("to_external conversion error") ); *to_next = '\0'; return std::string( work.get() ); } } // unnamed namespace // main ------------------------------------------------------------------------------// int main( int argc, char * /*argv*/[] ) { if ( argc > 1 ) cleanup = false; // So that tests are run with known encoding, use Boost UTF-8 codecvt std::locale global_loc = std::locale(); std::locale loc( global_loc, new fs::detail::utf8_codecvt_facet ); fs::wpath_traits::imbue( loc ); std::string s( to_external( L"\x2780" ) ); for (std::size_t i = 0; i < s.size(); ++i ) std::cout << std::hex << int( static_cast(s[i]) ) << " "; std::cout << std::dec << std::endl; BOOST_TEST( to_external( L"\x2780" ).size() == 3 ); BOOST_TEST( to_external( L"\x2780" ) == "\xE2\x9E\x80" ); // test fs::path std::cout << "begin path test..." << std::endl; test( fs::path( "foo" ), fs::path( "bar" ), fs::path( "." ) ); std::cout << "complete\n\n"; // test fs::wpath // x2780 is circled 1 against white background == e2 9e 80 in UTF-8 // x2781 is circled 2 against white background == e2 9e 81 in UTF-8 std::cout << "begin wpath test..." << std::endl; test( fs::wpath( L"\x2780" ), fs::wpath( L"\x2781" ), fs::wpath( L"." ) ); std::cout << "complete\n\n"; // test user supplied basic_path const long dir[] = { 'b', 'o', 'o', 0 }; const long file[] = { 'f', 'a', 'r', 0 }; const long dot[] = { '.', 0 }; std::cout << "begin lpath test..." << std::endl; test( ::user::lpath( dir ), ::user::lpath( file ), ::user::lpath( dot ) ); std::cout << "complete\n\n"; return ::boost::report_errors(); }