0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-18 07:50:57 +01:00

ircd::locale: Add char16_t conversion overloads for unterminated strings.

ircd::js: Use sized conversions when calling ircd::locale.
This commit is contained in:
Jason Volk 2016-11-04 14:46:42 -07:00
parent e6ba493bd3
commit fcc654699d
3 changed files with 109 additions and 3 deletions

View file

@ -56,6 +56,6 @@ ircd::js::native_external_copy(const char *const &s,
const size_t &len) const size_t &len)
{ {
auto buf(std::make_unique<char16_t[]>(len + 1)); auto buf(std::make_unique<char16_t[]>(len + 1));
ircd::locale::char16::conv(s, buf.get(), len + 1); ircd::locale::char16::conv(s, len, buf.get(), len + 1);
return buf; return buf;
} }

View file

@ -35,10 +35,18 @@ namespace char16
{ {
char conv(const char16_t &); char conv(const char16_t &);
char16_t conv(const char &); char16_t conv(const char &);
size_t conv(const char16_t *const &, const size_t &len, char *const &buf, const size_t &max);
size_t conv(const char *const &, const size_t &len, char16_t *const &buf, const size_t &max); // uint8_t = max*2
size_t conv(const char16_t *const &, char *const &buf, const size_t &max); size_t conv(const char16_t *const &, char *const &buf, const size_t &max);
size_t conv(const char *const &, char16_t *const &buf, const size_t &max); // uint8_t = max*2 size_t conv(const char *const &, char16_t *const &buf, const size_t &max); // uint8_t = max*2
std::string conv(const char16_t *const &, const size_t &len);
std::string conv(const char16_t *const &); std::string conv(const char16_t *const &);
std::string conv(const std::u16string &); std::string conv(const std::u16string &);
std::u16string conv(const char *const &, const size_t &len);
std::u16string conv(const char *const &); std::u16string conv(const char *const &);
std::u16string conv(const std::string &); std::u16string conv(const std::string &);
} }

View file

@ -59,6 +59,23 @@ ircd::locale::char16::conv(const char *const &s)
} }
#endif #endif
#ifdef HAVE_CODECVT
std::u16string
ircd::locale::char16::conv(const char *const &s,
const size_t &len)
{
static std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
return s && len? converter.from_bytes(s, s + len) : std::u16string{};
}
#else
std::u16string
ircd::locale::char16::conv(const char *const &s,
const size_t &len)
{
return boost::locale::conv::utf_to_utf<char16_t>(s, s + len);
}
#endif
#ifdef HAVE_CODECVT #ifdef HAVE_CODECVT
std::string std::string
ircd::locale::char16::conv(const std::u16string &s) ircd::locale::char16::conv(const std::u16string &s)
@ -89,6 +106,23 @@ ircd::locale::char16::conv(const char16_t *const &s)
} }
#endif #endif
#ifdef HAVE_CODECVT
std::string
ircd::locale::char16::conv(const char16_t *const &s,
const size_t &len)
{
static std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
return s && len? converter.to_bytes(s, s + len) : std::string{};
}
#else
std::string
ircd::locale::char16::conv(const char16_t *const &s,
const size_t &len)
{
return boost::locale::conv::utf_to_utf<char>(s, s + len);
}
#endif
#ifdef HAVE_CODECVT #ifdef HAVE_CODECVT
size_t size_t
ircd::locale::char16::conv(const char16_t *const &str, ircd::locale::char16::conv(const char16_t *const &str,
@ -104,8 +138,8 @@ ircd::locale::char16::conv(const char16_t *const &str,
#else #else
size_t size_t
ircd::locale::char16::conv(const char16_t *const &str, ircd::locale::char16::conv(const char16_t *const &str,
char *const &buf, char *const &buf,
const size_t &max) const size_t &max)
{ {
//TODO: optimize //TODO: optimize
const auto s(boost::locale::conv::utf_to_utf<char>(str)); const auto s(boost::locale::conv::utf_to_utf<char>(str));
@ -113,6 +147,32 @@ ircd::locale::char16::conv(const char16_t *const &str,
} }
#endif #endif
#ifdef HAVE_CODECVT
size_t
ircd::locale::char16::conv(const char16_t *const &str,
const size_t &len,
char *const &buf,
const size_t &max)
{
static std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
//TODO: optimize
const auto s(converter.to_bytes(str, str + len));
return rb_strlcpy(buf, s.c_str(), max);
}
#else
size_t
ircd::locale::char16::conv(const char16_t *const &str,
const size_t &len,
char *const &buf,
const size_t &max)
{
//TODO: optimize
const auto s(boost::locale::conv::utf_to_utf<char>(str, str + len));
return rb_strlcpy(buf, s.c_str(), max);
}
#endif
#ifdef HAVE_CODECVT #ifdef HAVE_CODECVT
size_t size_t
ircd::locale::char16::conv(const char *const &str, ircd::locale::char16::conv(const char *const &str,
@ -149,6 +209,44 @@ ircd::locale::char16::conv(const char *const &str,
} }
#endif #endif
#ifdef HAVE_CODECVT
size_t
ircd::locale::char16::conv(const char *const &str,
const size_t &len,
char16_t *const &buf,
const size_t &max)
{
static std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
if(unlikely(!max))
return 0;
//TODO: optimize
const auto s(converter.from_bytes(str, str + len));
const auto cpsz(std::min(s.size(), size_t(max - 1)));
memcpy(buf, s.data(), cpsz * 2);
buf[cpsz] = char16_t(0);
return cpsz;
}
#else
size_t
ircd::locale::char16::conv(const char *const &str,
const size_t &len,
char16_t *const &buf,
const size_t &max)
{
if(unlikely(!max))
return 0;
//TODO: optimize
const auto s(boost::locale::conv::utf_to_utf<char16_t>(str, str + len));
const auto cpsz(std::min(s.size(), size_t(max - 1)));
memcpy(buf, s.data(), cpsz * 2);
buf[cpsz] = char16_t(0);
return cpsz;
}
#endif
char16_t char16_t
ircd::locale::char16::conv(const char &c) ircd::locale::char16::conv(const char &c)
{ {