deduce the second argument to iconv() instead of requiring it to be configured via a macro

This commit is contained in:
arvidn 2017-10-05 12:09:24 +02:00 committed by Arvid Norberg
parent dfabce3854
commit ed31664ee3
2 changed files with 15 additions and 17 deletions

View File

@ -194,13 +194,6 @@ POSSIBILITY OF SUCH DAMAGE.
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
#define TORRENT_USE_EXECINFO 1
#endif
#else // __APPLE__
// FreeBSD has a reasonable iconv signature
// unless we're on glibc
#ifndef __GLIBC__
# define TORRENT_ICONV_ARG(x) (x)
#endif
#endif // __APPLE__
#define TORRENT_HAVE_MMAP 1
@ -344,7 +337,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_USE_IFCONF 1
#define TORRENT_USE_SYSCTL 1
#define TORRENT_USE_IPV6 0
#define TORRENT_ICONV_ARG(x) (x)
#define TORRENT_USE_WRITEV 0
#define TORRENT_USE_READV 0
@ -456,10 +448,6 @@ int snprintf(char* buf, int len, char const* fmt, ...)
#define TORRENT_OVERRIDE override
#endif
#ifndef TORRENT_ICONV_ARG
#define TORRENT_ICONV_ARG(x) const_cast<char**>(x)
#endif
#if defined __GNUC__ || defined __clang__
#define TORRENT_FORMAT(fmt, ellipsis) __attribute__((__format__(__printf__, fmt, ellipsis)))
#else

View File

@ -515,6 +515,17 @@ namespace libtorrent
#if TORRENT_USE_ICONV
namespace {
// this is a helper function to deduce the type of the second argument to
// the iconv() function.
template <typename Input>
size_t call_iconv(size_t (&fun)(iconv_t, Input**, size_t*, char**, size_t*)
, iconv_t cd, char const** in, size_t* insize, char** out, size_t* outsize)
{
return fun(cd, const_cast<Input**>(in), insize, out, outsize);
}
std::string iconv_convert_impl(std::string const& s, iconv_t h)
{
std::string ret;
@ -523,11 +534,10 @@ namespace {
ret.resize(outsize);
char const* in = s.c_str();
char* out = &ret[0];
// posix has a weird iconv signature. implementations
// differ on what this signature should be, so we use
// a macro to let config.hpp determine it
size_t retval = iconv(h, TORRENT_ICONV_ARG(&in), &insize,
&out, &outsize);
// posix has a weird iconv() signature. implementations
// differ on the type of the second parameter. We use a helper template
// to deduce what we need to cast to.
size_t const retval = call_iconv(::iconv, h, &in, &insize, &out, &outsize);
if (retval == size_t(-1)) return s;
// if this string has an invalid utf-8 sequence in it, don't touch it
if (insize != 0) return s;