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
#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

View File

@ -61,6 +61,15 @@ namespace libtorrent
std::string const& url, std::string argument);
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

View File

@ -81,12 +81,6 @@ namespace libtorrent
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(
file_storage const& t
, fs::path p);

View File

@ -48,6 +48,22 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/assert.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
{
@ -393,5 +409,50 @@ namespace libtorrent
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 <vector>
#if TORRENT_USE_WPATH
// for safe_convert
#include "libtorrent/storage.hpp"
#if TORRENT_USE_WPATH || TORRENT_USE_LOCALE_FILENAMES
// for convert_to_wstring and convert_to_native
#include "libtorrent/escape_string.hpp"
#endif
#include "libtorrent/assert.hpp"
@ -179,7 +179,7 @@ namespace libtorrent
};
#if TORRENT_USE_WPATH
m_path = safe_convert(path.external_file_string());
m_path = convert_to_wstring(path.external_file_string());
#else
m_path = utf8_native(path.external_file_string());
#endif
@ -220,8 +220,14 @@ namespace libtorrent
#else
static const int no_buffer_flag[] = {0, 0};
#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()
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
#endif
#ifdef TORRENT_LINUX
// workaround for linux bug

View File

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