uses iconv by default on linux to convert filenames from utf-8 to the current locale

This commit is contained in:
Arvid Norberg 2009-03-01 00:02:33 +00:00
parent c51f5863dd
commit b809028bda
6 changed files with 138 additions and 60 deletions

View File

@ -102,5 +102,13 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_UPNP_LOGGING #define TORRENT_UPNP_LOGGING
#endif #endif
#if !TORRENT_USE_WPATH && defined TORRENT_LINUX
// libiconv presnce, not implemented yet
#define TORRENT_USE_LOCALE_FILENAMES 1
#else
#define TORRENT_USE_LOCALE_FILENAMES 0
#endif
#endif // TORRENT_CONFIG_HPP_INCLUDED #endif // TORRENT_CONFIG_HPP_INCLUDED

View File

@ -61,6 +61,15 @@ namespace libtorrent
std::string const& url, std::string argument); std::string const& url, std::string argument);
TORRENT_EXPORT std::string to_hex(std::string const& s); TORRENT_EXPORT std::string to_hex(std::string const& s);
#if TORRENT_USE_WPATH
TORRENT_EXPORT std::wstring convert_to_wstring(std::string const& s);
#endif
#if TORRENT_USE_LOCALE_FILENAMES
TORRENT_EXPORT std::string convert_to_native(std::string const& s);
#endif
} }
#endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED #endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED

View File

@ -81,12 +81,6 @@ namespace libtorrent
storage_mode_compact storage_mode_compact
}; };
#if TORRENT_USE_WPATH
TORRENT_EXPORT std::wstring safe_convert(std::string const& s);
#endif
TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes( TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
file_storage const& t file_storage const& t
, fs::path p); , fs::path p);

View File

@ -48,6 +48,22 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/escape_string.hpp" #include "libtorrent/escape_string.hpp"
#if TORRENT_USE_WPATH
#ifdef BOOST_WINDOWS
#include <windows.h>
#endif
#include <boost/filesystem/exception.hpp>
#include "libtorrent/utf8.hpp"
#endif
#if TORRENT_USE_LOCALE_FILENAMES
#include <iconv.h>
#include <locale.h>
#endif
namespace libtorrent namespace libtorrent
{ {
@ -393,5 +409,50 @@ namespace libtorrent
return ret; return ret;
} }
#if TORRENT_USE_WPATH
std::wstring convert_to_wstring(std::string const& s)
{
std::wstring ret;
int result = libtorrent::utf8_wchar(s, ret);
#ifndef BOOST_WINDOWS
return ret;
#else
if (result == 0) return ret;
ret.clear();
const char* end = &s[0] + s.size();
for (const char* i = &s[0]; i < end;)
{
wchar_t c = '.';
int result = std::mbtowc(&c, i, end - i);
if (result > 0) i += result;
else ++i;
ret += c;
}
return ret;
#endif
}
#endif
#if TORRENT_USE_LOCALE_FILENAMES
std::string convert_to_native(std::string const& s)
{
// the empty string represents the local dependent encoding
static iconv_t iconv_handle = iconv_open("", "UTF-8");
if (iconv_handle == iconv_t(-1)) return s;
std::string ret;
size_t insize = s.size();
size_t outsize = insize * 4;
ret.resize(outsize);
char const* in = &s[0];
char* out = &ret[0];
size_t retval = iconv(iconv_handle, (char**)&in, &insize,
&out, &outsize);
if (retval == (size_t)-1) return s;
ret.resize(outsize);
return ret;
}
#endif
} }

View File

@ -65,9 +65,9 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH || TORRENT_USE_LOCALE_FILENAMES
// for safe_convert // for convert_to_wstring and convert_to_native
#include "libtorrent/storage.hpp" #include "libtorrent/escape_string.hpp"
#endif #endif
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
@ -179,7 +179,7 @@ namespace libtorrent
}; };
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
m_path = safe_convert(path.external_file_string()); m_path = convert_to_wstring(path.external_file_string());
#else #else
m_path = utf8_native(path.external_file_string()); m_path = utf8_native(path.external_file_string());
#endif #endif
@ -220,8 +220,14 @@ namespace libtorrent
#else #else
static const int no_buffer_flag[] = {0, 0}; static const int no_buffer_flag[] = {0, 0};
#endif #endif
#if TORRENT_USE_LOCALE_FILENAMES
m_fd = ::open(convert_to_native(path.external_file_string()).c_str()
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
#else
m_fd = ::open(path.external_file_string().c_str() m_fd = ::open(path.external_file_string().c_str()
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions); , mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
#endif
#ifdef TORRENT_LINUX #ifdef TORRENT_LINUX
// workaround for linux bug // workaround for linux bug

View File

@ -100,43 +100,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/mount.h> #include <sys/mount.h>
#endif #endif
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH || TORRENT_USE_LOCALE_FILENAMES
// for convert_to_wstring and convert_to_native
#ifdef BOOST_WINDOWS #include "libtorrent/escape_string.hpp"
#include <windows.h>
#else
#include <fcntl.h>
#endif
#include <boost/filesystem/exception.hpp>
#include "libtorrent/utf8.hpp"
#include "libtorrent/buffer.hpp"
namespace libtorrent
{
std::wstring safe_convert(std::string const& s)
{
std::wstring ret;
int result = libtorrent::utf8_wchar(s, ret);
#ifndef BOOST_WINDOWS
return ret;
#else
if (result == 0) return ret;
ret.clear();
const char* end = &s[0] + s.size();
for (const char* i = &s[0]; i < end;)
{
wchar_t c = '.';
int result = std::mbtowc(&c, i, end - i);
if (result > 0) i += result;
else ++i;
ret += c;
}
return ret;
#endif
}
}
#endif #endif
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -222,7 +188,9 @@ namespace libtorrent
size_type size = 0; size_type size = 0;
std::time_t time = 0; std::time_t time = 0;
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath f = safe_convert((p / i->path).string()); fs::wpath f = convert_to_wstring((p / i->path).string());
#elif TORRENT_USE_LOCALE_FILENAMES
fs::path f = convert_to_native((p / i->path).string());
#else #else
fs::path f = p / i->path; fs::path f = p / i->path;
#endif #endif
@ -273,7 +241,9 @@ namespace libtorrent
if (i->pad_file) continue; if (i->pad_file) continue;
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath f = safe_convert((p / i->path).string()); fs::wpath f = convert_to_wstring((p / i->path).string());
#elif TORRENT_USE_LOCALE_FILENAMES
fs::path f = convert_to_native(p / i->path);
#else #else
fs::path f = p / i->path; fs::path f = p / i->path;
#endif #endif
@ -535,9 +505,13 @@ namespace libtorrent
last_path = dir; last_path = dir;
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath wp = safe_convert(last_path.string()); fs::wpath wp = convert_to_wstring(last_path.string());
if (!exists(wp)) if (!exists(wp))
create_directories(wp); create_directories(wp);
#elif TORRENT_USE_LOCALE_FILENAMES
fs::path p = convert_to_native(last_path.string());
if (!exists(p))
create_directories(p);
#else #else
if (!exists(last_path)) if (!exists(last_path))
create_directories(last_path); create_directories(last_path);
@ -558,7 +532,7 @@ namespace libtorrent
#endif #endif
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath file_path = safe_convert((m_save_path / file_iter->path).string()); fs::wpath file_path = convert_to_wstring((m_save_path / file_iter->path).string());
#else #else
fs::path file_path = m_save_path / file_iter->path; fs::path file_path = m_save_path / file_iter->path;
#endif #endif
@ -609,8 +583,11 @@ namespace libtorrent
m_pool.release(old_name); m_pool.release(old_name);
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath old_path = safe_convert(old_name.string()); fs::wpath old_path = convert_to_wstring(old_name.string());
fs::wpath new_path = safe_convert((m_save_path / new_filename).string()); fs::wpath new_path = convert_to_wstring((m_save_path / new_filename).string());
#elif TORRENT_USE_LOCALE_FILENAMES
fs::path const& old_path = convert_to_native(old_name.string());
fs::path new_path = convert_to_native((m_save_path / new_filename).string());
#else #else
fs::path const& old_path = old_name; fs::path const& old_path = old_name;
fs::path new_path = m_save_path / new_filename; fs::path new_path = m_save_path / new_filename;
@ -686,12 +663,18 @@ namespace libtorrent
} }
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
try try
{ fs::remove(safe_convert(p)); } { fs::remove(convert_to_wstring(p)); }
catch (std::exception& e) catch (std::exception& e)
{ {
error = errno; error = errno;
error_file = p; error_file = p;
} }
#elif TORRENT_USE_LOCALE_FILENAMES
if (std::remove(convert_to_native(p).c_str()) != 0 && errno != ENOENT)
{
error = errno;
error_file = p;
}
#else #else
if (std::remove(p.c_str()) != 0 && errno != ENOENT) if (std::remove(p.c_str()) != 0 && errno != ENOENT)
{ {
@ -709,12 +692,18 @@ namespace libtorrent
{ {
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
try try
{ fs::remove(safe_convert(*i)); } { fs::remove(convert_to_wstring(*i)); }
catch (std::exception& e) catch (std::exception& e)
{ {
error = errno; error = errno;
error_file = *i; error_file = *i;
} }
#elif TORRENT_USE_LOCALE_FILENAMES
if (std::remove(convert_to_native(*i).c_str()) != 0 && errno != ENOENT)
{
error = errno;
error_file = *i;
}
#else #else
if (std::remove(i->c_str()) != 0 && errno != ENOENT) if (std::remove(i->c_str()) != 0 && errno != ENOENT)
{ {
@ -903,9 +892,9 @@ namespace libtorrent
} }
} }
} }
return match_filesizes(files(), m_save_path, file_sizes return match_filesizes(files(), m_save_path, file_sizes
, !full_allocation_mode, &error); , !full_allocation_mode, &error);
} }
// returns true on success // returns true on success
@ -922,11 +911,17 @@ namespace libtorrent
save_path = complete(save_path); save_path = complete(save_path);
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath wp = safe_convert(save_path.string()); fs::wpath wp = convert_to_wstring(save_path.string());
if (!exists(wp)) if (!exists(wp))
create_directory(wp); create_directory(wp);
else if (!is_directory(wp)) else if (!is_directory(wp))
return false; return false;
#elif TORRENT_USE_LOCALE_FILENAMES
fs::path p = convert_to_native(save_path.string());
if (!exists(p))
create_directory(p);
else if (!is_directory(p))
return false;
#else #else
if (!exists(save_path)) if (!exists(save_path))
create_directory(save_path); create_directory(save_path);
@ -937,8 +932,11 @@ namespace libtorrent
m_pool.release(this); m_pool.release(this);
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
old_path = safe_convert((m_save_path / files().name()).string()); old_path = convert_to_wstring((m_save_path / files().name()).string());
new_path = safe_convert((save_path / files().name()).string()); new_path = convert_to_wstring((save_path / files().name()).string());
#elif TORRENT_USE_LOCALE_FILENAMES
old_path = convert_to_native((m_save_path / files().name()).string());
new_path = convert_to_native((save_path / files().name().string()));
#else #else
old_path = m_save_path / files().name(); old_path = m_save_path / files().name();
new_path = save_path / files().name(); new_path = save_path / files().name();
@ -1858,8 +1856,10 @@ ret:
{ {
#endif #endif
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
fs::wpath wf = safe_convert(f.string()); fs::wpath wf = convert_to_wstring(f.string());
file_exists = exists(wf); file_exists = exists(wf);
#elif TORRENT_USE_LOCALE_FILENAMES
file_exists = exists(convert_to_native(f.string()));
#else #else
file_exists = exists(f); file_exists = exists(f);
#endif #endif