|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r50448 - in sandbox/filesystem-v3: boost/filesystem libs/filesystem/src libs/filesystem/test
From: bdawes_at_[hidden]
Date: 2009-01-03 09:36:52
Author: bemandawes
Date: 2009-01-03 09:36:50 EST (Sat, 03 Jan 2009)
New Revision: 50448
URL: http://svn.boost.org/trac/boost/changeset/50448
Log:
filesystem.v3: all tests (including imbue related tests) passing on Windows
Text files modified:
sandbox/filesystem-v3/boost/filesystem/path.hpp | 1
sandbox/filesystem-v3/libs/filesystem/src/path.cpp | 118 ++++++++++++++++++++++++---------------
sandbox/filesystem-v3/libs/filesystem/test/path_test.cpp | 6 +-
sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp | 7 +
4 files changed, 82 insertions(+), 50 deletions(-)
Modified: sandbox/filesystem-v3/boost/filesystem/path.hpp
==============================================================================
--- sandbox/filesystem-v3/boost/filesystem/path.hpp (original)
+++ sandbox/filesystem-v3/boost/filesystem/path.hpp 2009-01-03 09:36:50 EST (Sat, 03 Jan 2009)
@@ -18,6 +18,7 @@
* Windows, POSIX, conversions for char16_t, char32_t for supporting compilers.
* Windows, POSIX, conversions for user-defined types.
+ * Need an error category for codecvt errors. Seed path.cpp detail::append, etc.
* Add Alternate Data Stream test cases. See http://en.wikipedia.org/wiki/NTFS Features.
* test case: relational on paths differing only in trailing separator. rationale?
* Behavior of root_path() has been changed. Change needs to be propagated to trunk.
Modified: sandbox/filesystem-v3/libs/filesystem/src/path.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/src/path.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/src/path.cpp 2009-01-03 09:36:50 EST (Sat, 03 Jan 2009)
@@ -28,6 +28,10 @@
using boost::system::error_code;
+#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
+# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
+#endif
+
//--------------------------------------------------------------------------------------//
// //
// class path helpers //
@@ -44,6 +48,8 @@
typedef path::string_type string_type;
typedef path::value_type value_type;
+ const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
+
# ifdef BOOST_WINDOWS_PATH
const wchar_t separator = L'/';
@@ -579,8 +585,8 @@
// //
// class windows_file_api_codecvt_facet //
// //
- // Warning: partial implementation; only do_in and do_out meet the standard library //
- // specifications, and even these do not set from_next. //
+ // Warning: partial implementation; even do_in and do_out only partially meet the //
+ // standard library specifications; the "to" buffer must hold the entire result. //
//------------------------------------------------------------------------------------//
class windows_file_api_codecvt_facet
@@ -628,6 +634,7 @@
return error; // conversion failed
}
+ from_next = from_end;
to_next = to + count;
*to_next = L'\0';
return ok;
@@ -647,6 +654,7 @@
return error; // conversion failed
}
+ from_next = from_end;
to_next = to + count;
*to_next = '\0';
return ok;
@@ -733,11 +741,27 @@
// append //
//------------------------------------------------------------------------------------//
- void append_error( const char * begin, const char * end )
+ // actual append done here to factor it out from messy buffer management code;
+ // this function just assumes the buffer is large enough.
+ inline void do_append( const char * from, const char * from_end,
+ wchar_t * to, wchar_t * to_end,
+ wstring & target, error_code & ec )
{
- assert( false && "not implemented yet" );
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const char * from_next;
+ wchar_t * to_next;
+
+ if ( wchar_t_codecvt_facet()->in( state, from, from_end, from_next,
+ to, to_end, to_next ) != std::codecvt_base::ok )
+ {
+ assert( 0 && "append error handling not implemented yet" );
+ throw "append error handling not implemented yet";
+ }
+ if ( &ec != &system::throws ) ec.clear();
+ target.append( to, to_next );
}
+ BOOST_FILESYSTEM_DECL
void append( const char * begin, const char * end, wstring & target, error_code & ec )
{
if ( !end )
@@ -749,68 +773,72 @@
return;
}
- std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
- const char * from_next;
- wchar_t * to_next;
std::size_t buf_size = end - begin; // perhaps too large, but that's OK
- const std::size_t max_size = 128;
// dynamically allocate a buffer only if source is unusually large
- if ( buf_size <= max_size )
+ if ( buf_size > default_codecvt_buf_size )
{
- wchar_t buf[max_size];
- if ( wchar_t_codecvt_facet()->in( state, begin, end,
- from_next, buf, buf+max_size, to_next ) != std::codecvt_base::ok )
- append_error( begin, end );
- else {
- target.append( buf, to_next );
- if ( &ec != &system::throws ) ec.clear();
- }
+ boost::scoped_array< wchar_t > buf( new wchar_t [buf_size] );
+ do_append( begin, end, buf.get(), buf.get()+buf_size, target, ec );
}
else
{
- boost::scoped_array< wchar_t > buf( new wchar_t [ buf_size] );
- if ( wchar_t_codecvt_facet()->in( state, begin, end,
- from_next, buf.get(), buf.get()+buf_size, to_next ) != std::codecvt_base::ok )
- append_error( begin, end );
- else {
- target.append( buf.get(), to_next );
- if ( &ec != &system::throws ) ec.clear();
- }
+ wchar_t buf[default_codecvt_buf_size];
+ do_append( begin, end, buf, buf+buf_size, target, ec );
}
-
}
//------------------------------------------------------------------------------------//
// convert //
//------------------------------------------------------------------------------------//
- BOOST_FILESYSTEM_DECL
- string convert_to_string( const wstring & src, error_code & ec )
+ // actual convert done here to factor it out from messy buffer management code;
+ // this function just assumes the buffer is large enough.
+ inline string do_convert( const wchar_t * from, const wchar_t * from_end,
+ char * to, char * to_end, error_code & ec )
{
- if ( src.empty() ) return std::string();
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const wchar_t * from_next;
+ char * to_next;
- UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP;
+ if ( wchar_t_codecvt_facet()->out( state, from, from_end,
+ from_next, to, to_end, to_next ) != std::codecvt_base::ok )
+ {
+ assert( 0 && "convert error handling not implemented yet" );
+ throw "convert error handling not implemented yet";
+ }
+ if ( &ec != &system::throws ) ec.clear();
+ return string( to, to_next );
+ }
- // buffer management strategy; use a probably large enough default buffer,
- // but fallback to an explict allocation if the default buffer is too small
+ BOOST_FILESYSTEM_DECL
+ string convert_to_string( const wstring & src, error_code & ec )
+ {
+ if ( src.empty() )
+ {
+ if ( &ec != &system::throws ) ec.clear();
+ return std::string();
+ }
- const std::size_t default_buf_sz = MAX_PATH+1;
- char buf[default_buf_sz+1];
- int count;
+ // The codecvt length functions may not be implemented, and I don't reall
+ // understand them either. Thus this code is really just a guess; it it turns
+ // out the buffer is too small then an error will be reported and the code
+ // will have to be fixed.
+ std::size_t buf_size = src.size() * 4;
+ buf_size += 4; // encodings like shift-JIS need some prefix space
- if ( (count = ::WideCharToMultiByte( codepage, WC_NO_BEST_FIT_CHARS, src.c_str(),
- src.size(), buf, default_buf_sz, 0, 0 )) != 0 ) // success
+ // dynamically allocate a buffer only if source is unusually large
+ if ( buf_size > default_codecvt_buf_size )
{
- ec.clear();
- buf[count] = '\0';
- return std::string( buf );
+ boost::scoped_array< char > buf( new char [buf_size] );
+ return do_convert( src.c_str(), src.c_str()+src.size(),
+ buf.get(), buf.get()+buf_size, ec );
+ }
+ else
+ {
+ char buf[default_codecvt_buf_size];
+ return do_convert( src.c_str(), src.c_str()+src.size(), buf, buf+buf_size, ec );
}
-
- // TODO: implement fallback
- BOOST_ASSERT(0);
- throw "path::native_string() error handling not implemented yet";
- return std::string();
}
} // namespace detail
Modified: sandbox/filesystem-v3/libs/filesystem/test/path_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/path_test.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/test/path_test.cpp 2009-01-03 09:36:50 EST (Sat, 03 Jan 2009)
@@ -1258,12 +1258,12 @@
p5 /= "";
PATH_CHECK( p5, "foo/bar\\" );
char bf[]= "bar/foo";
- p5.assign( bf, bf + sizeof(bf) );
+ p5.assign( bf, bf + sizeof(bf) - 1 );
PATH_CHECK( p5, bf );
- p5.append( bf, bf + sizeof(bf) );
+ p5.append( bf, bf + sizeof(bf) - 1 );
PATH_CHECK( p5, "bar/foo\\bar/foo" );
- // this code, courtesy of David Whetstone, detected a now fixed bug that
+ // this code, courtesy of David Whetstone, detects a now fixed bug that
// derefereced the end iterator (assuming debug build with checked itors)
std::vector<char> v1;
p5.assign( v1.begin(), v1.end() );
Modified: sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp 2009-01-03 09:36:50 EST (Sat, 03 Jan 2009)
@@ -522,9 +522,11 @@
path p0( L"\u2722" ); // for tests that depend on detail::convert_to_string
CHECK( p0.string() != "\xE2\x9C\xA2" );
+ string p0_string( p0.string() );
path p1( "\xE2\x9C\xA2" );
CHECK( p1 != L"\u2722" );
+ wstring p1_wstring( p1.wstring() );
// So that tests are run with known encoding, use Boost UTF-8 codecvt
std::locale global_loc = std::locale();
@@ -534,13 +536,14 @@
CHECK( p0.string() == "\xE2\x9C\xA2" );
path p2( "\xE2\x9C\xA2" );
CHECK( p2 == L"\u2722" );
+ CHECK( p2.wstring() == L"\u2722" );
path::imbue( old_loc );
- CHECK( p0.string() != "\xE2\x9C\xA2" );
+ CHECK( p0.string() == p0_string );
path p3( "\xE2\x9C\xA2" );
CHECK( p3 != L"\u2722" );
-
+ CHECK( p3.wstring() == p1_wstring );
}
// // test_locales --------------------------------------------------------------------//
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk