//  path.cpp  ----------------------------------------------------------------//

//  Copyright 2005 Beman Dawes

//  Distributed under 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

//----------------------------------------------------------------------------// 

// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_FILESYSTEM_SOURCE 

#ifndef BOOST_SYSTEM_NO_DEPRECATED 
# define BOOST_SYSTEM_NO_DEPRECATED
#endif

#include <boost/filesystem/v2/config.hpp>

#ifndef BOOST_FILESYSTEM2_NARROW_ONLY

#include <boost/filesystem/v2/path.hpp>
#include <boost/scoped_array.hpp>

#include <locale>
#include <boost/cerrno.hpp>
#include <boost/system/error_code.hpp>

#include <cwchar>     // for std::mbstate_t

#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) 
# include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#endif


namespace
{
  // std::locale construction can throw (if LC_MESSAGES is wrong, for example),
  // so a static at function scope is used to ensure that exceptions can be
  // caught. (A previous version was at namespace scope, so initialization
  // occurred before main(), preventing exceptions from being caught.)
  std::locale & loc()
  {
#if !defined(macintosh) && !defined(__APPLE__) && !defined(__APPLE_CC__) 
    // ISO C calls this "the locale-specific native environment":
    static std::locale lc;
#else  // Mac OS
    // "All BSD system functions expect their string parameters to be in UTF-8 encoding
    // and nothing else."
    // See http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html
    std::locale global_loc = std::locale();  // Mac OS doesn't support locale("")
    static std::locale lc(global_loc,
        new boost::filesystem::detail::utf8_codecvt_facet);  
#endif
    return lc;
  }

  const std::codecvt<wchar_t, char, std::mbstate_t> *&
  converter()
  {
   static const std::codecvt<wchar_t, char, std::mbstate_t> *
     cvtr(
       &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
        ( loc() ) );
   return cvtr;
  }

  bool locked(false);
} // unnamed namespace

namespace boost
{
  namespace filesystem2
  {
    bool wpath_traits::imbue( const std::locale & new_loc, const std::nothrow_t & )
    {
      if ( locked ) return false;
      locked = true;
      loc() = new_loc;
      converter() = &std::use_facet
        <std::codecvt<wchar_t, char, std::mbstate_t> >( loc() );
      return true;
    }

    void wpath_traits::imbue( const std::locale & new_loc )
    {
      if ( locked ) boost::throw_exception(
        wfilesystem_error(
          "boost::filesystem::wpath_traits::imbue() after lockdown",
          make_error_code( system::errc::not_supported ) ) );
      imbue( new_loc, std::nothrow );
    }

    //namespace detail
    //{
    //  BOOST_FILESYSTEM_DECL
    //  const char * what( const char * sys_err_what,
    //    const path & path1, const path & path2, std::string & target)
    //  {
    //    try
    //    {
    //      if ( target.empty() )
    //      {
    //        target = sys_err_what;
    //        if ( !path1.empty() )
    //        {
    //          target += ": \"";
    //          target += path1.file_string();
    //          target += "\"";
    //        }
    //        if ( !path2.empty() )
    //        {
    //          target += ", \"";
    //          target += path2.file_string();
    //          target += "\"";
    //        }
    //      }
    //      return target.c_str();
    //    }
    //    catch (...)
    //    {
    //      return sys_err_what;
    //    }
    //  }
    //}
    
# ifdef BOOST_POSIX_API

//  Because this is POSIX only code, we don't have to worry about ABI issues
//  described in http://www.boost.org/more/separate_compilation.html

    wpath_traits::external_string_type
    wpath_traits::to_external( const wpath & ph, 
      const internal_string_type & src )
    {
      locked = true;
      std::size_t work_size( converter()->max_length() * (src.size()+1) );
      boost::scoped_array<char> work( new char[ work_size ] );
      std::mbstate_t state = std::mbstate_t();  // perhaps unneeded, but cuts bug reports
      const internal_string_type::value_type * from_next;
      external_string_type::value_type * to_next;
      if ( converter()->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( boost::filesystem::wfilesystem_error(
          "boost::filesystem::wpath::to_external conversion error",
          ph, system::error_code( system::errc::invalid_argument, system::system_category() ) ) );
      *to_next = '\0';
      return external_string_type( work.get() );
    }

    wpath_traits::internal_string_type
    wpath_traits::to_internal( const external_string_type & src )
    {
      locked = true;
      std::size_t work_size( src.size()+1 );
      boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] );
      std::mbstate_t state  = std::mbstate_t();  // perhaps unneeded, but cuts bug reports
      const external_string_type::value_type * from_next;
      internal_string_type::value_type * to_next;
      if ( converter()->in( 
        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( boost::filesystem::wfilesystem_error(
          "boost::filesystem::wpath::to_internal conversion error",
          system::error_code( system::errc::invalid_argument, system::system_category() ) ) );
      *to_next = L'\0';
      return internal_string_type( work.get() );
    }
# endif // BOOST_POSIX_API

  } // namespace filesystem2
} // namespace boost

#endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY
