Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55374 - in sandbox/filesystem-v3: boost/filesystem/detail libs/filesystem/src
From: bdawes_at_[hidden]
Date: 2009-08-02 18:10:12


Author: bemandawes
Date: 2009-08-02 18:10:12 EDT (Sun, 02 Aug 2009)
New Revision: 55374
URL: http://svn.boost.org/trac/boost/changeset/55374

Log:
Factor convert() and supporting code into separate header, src
Added:
   sandbox/filesystem-v3/boost/filesystem/detail/
   sandbox/filesystem-v3/boost/filesystem/detail/convert.hpp (contents, props changed)
   sandbox/filesystem-v3/libs/filesystem/src/convert.cpp (contents, props changed)

Added: sandbox/filesystem-v3/boost/filesystem/detail/convert.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/detail/convert.hpp 2009-08-02 18:10:12 EDT (Sun, 02 Aug 2009)
@@ -0,0 +1,105 @@
+// filesystem convert.hpp ------------------------------------------------------------//
+
+// Copyright Beman Dawes 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#ifndef BOOST_FILESYSTEM_CONVERT_HPP
+#define BOOST_FILESYSTEM_CONVERT_HPP
+
+#include <boost/filesystem/config.hpp>
+#include <string>
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+namespace boost { namespace filesystem {
+
+ typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
+
+namespace detail {
+
+ // value types differ ---------------------------------------------------------------//
+ //
+ // A from_end argument of 0 is less efficient than a known end, so use only if needed
+
+ BOOST_FILESYSTEM_DECL
+ void convert( const char * from,
+ const char * from_end, // 0 for null terminated MBCS
+ std::wstring & to,
+ const codecvt_type & cvt );
+
+ BOOST_FILESYSTEM_DECL
+ void convert( const wchar_t * from,
+ const wchar_t * from_end, // 0 for null terminated MBCS
+ std::string & to,
+ const codecvt_type & cvt );
+
+ inline
+ void convert( const char * from,
+ std::wstring & to,
+ const codecvt_type & cvt )
+ {
+ BOOST_ASSERT( from );
+ convert( from, 0, to, cvt );
+ }
+
+ inline
+ void convert( const wchar_t * from,
+ std::string & to,
+ const codecvt_type & cvt )
+ {
+ BOOST_ASSERT( from );
+ convert( from, 0, to, cvt );
+ }
+
+ // value types same -----------------------------------------------------------------//
+
+ // char
+
+ inline
+ void convert( const char * from, const char * from_end, std::string & to,
+ const codecvt_type & )
+ {
+ BOOST_ASSERT( from );
+ BOOST_ASSERT( from_end );
+ to.append( from, from_end );
+ }
+
+ inline
+ void convert( const char * from,
+ std::string & to,
+ const codecvt_type & )
+ {
+ BOOST_ASSERT( from );
+ to += from;
+ }
+
+ // wchar_t
+
+ inline
+ void convert( const wchar_t * from, const wchar_t * from_end, std::wstring & to,
+ const codecvt_type & )
+ {
+ BOOST_ASSERT( from );
+ BOOST_ASSERT( from_end );
+ to.append( from, from_end );
+ }
+
+ inline
+ void convert( const wchar_t * from,
+ std::wstring & to,
+ const codecvt_type & )
+ {
+ BOOST_ASSERT( from );
+ to += from;
+ }
+
+}}} // namespace boost::filesystem::detail
+
+#endif // BOOST_FILESYSTEM_CONVERT_HPP

Added: sandbox/filesystem-v3/libs/filesystem/src/convert.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/src/convert.cpp 2009-08-02 18:10:12 EDT (Sun, 02 Aug 2009)
@@ -0,0 +1,180 @@
+// filesystem convert.cpp ------------------------------------------------------------//
+
+// Copyright Beman Dawes 2008, 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem/detail/convert.hpp>
+#include <boost/filesystem/config.hpp>
+#include <boost/scoped_array.hpp>
+#include <cstring> // for strlen
+#include <cwchar> // for wcslen
+
+//--------------------------------------------------------------------------------------//
+// configuration //
+//--------------------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
+# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
+#endif
+
+namespace {
+
+ const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
+
+
+//--------------------------------------------------------------------------------------//
+// //
+// The public convert() functions do buffer management, and then forward to the //
+// convert_aux() functions for the actual call to the codecvt facet. //
+// //
+//--------------------------------------------------------------------------------------//
+
+//--------------------------------------------------------------------------------------//
+// convert_aux const char * to wstring //
+//--------------------------------------------------------------------------------------//
+
+ void convert_aux(
+ const char * from,
+ const char * from_end,
+ wchar_t * to, wchar_t * to_end,
+ std::wstring & target,
+ const boost::filesystem::codecvt_type & cvt )
+ {
+ //std::cout << std::hex
+ // << " from=" << std::size_t(from)
+ // << " from_end=" << std::size_t(from_end)
+ // << " to=" << std::size_t(to)
+ // << " to_end=" << std::size_t(to_end)
+ // << std::endl;
+
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const char * from_next;
+ wchar_t * to_next;
+
+ std::codecvt_base::result res;
+
+ if ( (res=cvt.in( state, from, from_end, from_next,
+ to, to_end, to_next )) != std::codecvt_base::ok )
+ {
+ //std::cout << " result is " << static_cast<int>(res) << std::endl;
+ assert( 0 && "append error handling not implemented yet" );
+ throw "append error handling not implemented yet";
+ }
+ target.append( to, to_next );
+ }
+
+//--------------------------------------------------------------------------------------//
+// convert_aux const wchar_t * to string //
+//--------------------------------------------------------------------------------------//
+
+ void convert_aux(
+ const wchar_t * from,
+ const wchar_t * from_end,
+ char * to, char * to_end,
+ std::string & target,
+ const boost::filesystem::codecvt_type & cvt )
+ {
+ //std::cout << std::hex
+ // << " from=" << std::size_t(from)
+ // << " from_end=" << std::size_t(from_end)
+ // << " to=" << std::size_t(to)
+ // << " to_end=" << std::size_t(to_end)
+ // << std::endl;
+
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const wchar_t * from_next;
+ char * to_next;
+
+ std::codecvt_base::result res;
+
+ if ( (res=cvt.out( state, from, from_end, from_next,
+ to, to_end, to_next )) != std::codecvt_base::ok )
+ {
+ //std::cout << " result is " << static_cast<int>(res) << std::endl;
+ assert( 0 && "append error handling not implemented yet" );
+ throw "append error handling not implemented yet";
+ }
+ target.append( to, to_next );
+ }
+
+} // unnamed namespace
+
+namespace boost { namespace filesystem { namespace detail {
+
+//--------------------------------------------------------------------------------------//
+// convert const char * to wstring //
+//--------------------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ void convert( const char * from,
+ const char * from_end, // 0 for null terminated MBCS
+ std::wstring & to,
+ const codecvt_type & cvt )
+ {
+ BOOST_ASSERT( from );
+
+ if ( !from_end ) // null terminated
+ {
+ from_end = from + std::strlen( from );
+ }
+
+ if ( from == from_end ) return;
+
+ std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK
+
+ // dynamically allocate a buffer only if source is unusually large
+ if ( buf_size > default_codecvt_buf_size )
+ {
+ boost::scoped_array< wchar_t > buf( new wchar_t [buf_size] );
+ convert_aux( from, from_end, buf.get(), buf.get()+buf_size, to, cvt );
+ }
+ else
+ {
+ wchar_t buf[default_codecvt_buf_size];
+ convert_aux( from, from_end, buf, buf+default_codecvt_buf_size, to, cvt );
+ }
+ }
+
+//--------------------------------------------------------------------------------------//
+// convert const wchar_t * to string //
+//--------------------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ void convert( const wchar_t * from,
+ const wchar_t * from_end, // 0 for null terminated MBCS
+ std::string & to,
+ const codecvt_type & cvt )
+ {
+ BOOST_ASSERT( from );
+
+ if ( !from_end ) // null terminated
+ {
+ from_end = from + std::wcslen( from );
+ }
+
+ if ( from == from_end ) return;
+
+ // The codecvt length functions may not be implemented, and I don't really
+ // understand them either. Thus this code is just a guess; if 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 = (from_end - from) * 4; // perhaps too large, but that's OK
+ buf_size += 4; // encodings like shift-JIS need some prefix space
+
+ // dynamically allocate a buffer only if source is unusually large
+ if ( buf_size > default_codecvt_buf_size )
+ {
+ boost::scoped_array< char > buf( new char [buf_size] );
+ convert_aux( from, from_end, buf.get(), buf.get()+buf_size, to, cvt );
+ }
+ else
+ {
+ char buf[default_codecvt_buf_size];
+ convert_aux( from, from_end, buf, buf+default_codecvt_buf_size, to, cvt );
+ }
+ }
+}}} // namespace boost::filesystem::detail


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