Use the standard library to convert between UTF-8 and UTF-16 where possible

This commit is contained in:
Tsuda Kageyu 2013-03-18 06:18:50 +09:00
parent a842220fe6
commit c86ea7bdff

View File

@ -24,13 +24,24 @@
***************************************************************************/
#include "tstring.h"
#include "unicode.h"
#include "tdebug.h"
#include "tstringlist.h"
#include <iostream>
#include <string.h>
// Determine if the compiler supports codecvt.
#if (defined(_MSC_VER) && _MSC_VER >= 1600) // VC++2010 or later
# define TAGLIB_USE_CODECVT
#endif
#ifdef TAGLIB_USE_CODECVT
# include <codecvt>
typedef std::codecvt_utf8_utf16<wchar_t> utf8_utf16_t;
#else
# include "unicode.h"
#endif
using namespace TagLib;
namespace {
@ -215,6 +226,20 @@ std::string String::to8Bit(bool unicode) const
else {
s.resize(d->data.size() * 4 + 1);
#ifdef TAGLIB_USE_CODECVT
std::mbstate_t st = 0;
const wchar_t *source;
char *target;
std::codecvt_base::result result = utf8_utf16_t().out(
st, &d->data[0], &d->data[d->data.size()], source, &s[0], &s[s.size()], target);
if(result != utf8_utf16_t::ok) {
debug("String::copyFromUTF8() - Unicode conversion error.");
}
#else
const Unicode::UTF16 *source = &d->data[0];
Unicode::UTF8 *target = reinterpret_cast<Unicode::UTF8*>(&s[0]);
@ -227,6 +252,8 @@ std::string String::to8Bit(bool unicode) const
debug("String::to8Bit() - Unicode conversion error.");
}
#endif
s.resize(::strlen(s.c_str()));
}
@ -379,8 +406,38 @@ ByteVector String::data(Type t) const
}
case UTF8:
{
std::string s = to8Bit(true);
v.setData(s.c_str(), static_cast<TagLib::uint>(s.length()));
v.resize(d->data.size() * 4 + 1);
#ifdef TAGLIB_USE_CODECVT
std::mbstate_t st = 0;
const wchar_t *source;
char *target;
std::codecvt_base::result result = utf8_utf16_t().out(
st, &d->data[0], &d->data[d->data.size()], source, v.data(), v.data() + v.size(), target);
if(result != utf8_utf16_t::ok) {
debug("String::copyFromUTF8() - Unicode conversion error.");
}
#else
const Unicode::UTF16 *source = &d->data[0];
Unicode::UTF8 *target = reinterpret_cast<Unicode::UTF8*>(v.data());
Unicode::ConversionResult result = Unicode::ConvertUTF16toUTF8(
&source, source + d->data.size(),
&target, target + v.size(),
Unicode::lenientConversion);
if(result != Unicode::conversionOK) {
debug("String::to8Bit() - Unicode conversion error.");
}
#endif
v.resize(::strlen(v.data()) + 1);
break;
}
case UTF16:
@ -730,6 +787,20 @@ void String::copyFromUTF8(const char *s, size_t length)
{
d->data.resize(length);
#ifdef TAGLIB_USE_CODECVT
std::mbstate_t st = 0;
const char *source;
wchar_t *target;
std::codecvt_base::result result = utf8_utf16_t().in(
st, s, s + length, source, &d->data[0], &d->data[d->data.size()], target);
if(result != utf8_utf16_t::ok) {
debug("String::copyFromUTF8() - Unicode conversion error.");
}
#else
const Unicode::UTF8 *source = reinterpret_cast<const Unicode::UTF8 *>(s);
Unicode::UTF16 *target = &d->data[0];
@ -738,11 +809,13 @@ void String::copyFromUTF8(const char *s, size_t length)
&target, target + length,
Unicode::lenientConversion);
d->data.resize(::wcslen(d->data.c_str()));
if(result != Unicode::conversionOK) {
debug("String::copyFromUTF8() - Unicode conversion error.");
}
#endif
d->data.resize(::wcslen(d->data.c_str()));
}
void String::copyFromUTF16(const wchar_t *s, size_t length, Type t)