X-Git-Url: https://git.sesse.net/?p=ccbs;a=blobdiff_plain;f=bigscreen%2Fwidestring.cpp;h=f486aaec8dde5e9b5ec96a811324ed92839aa1d8;hp=52b7f559e48acf406ecb58e9bb008369b4ccd0a3;hb=HEAD;hpb=da6c03044674863de9f8a017010aa579b3b27a12 diff --git a/bigscreen/widestring.cpp b/bigscreen/widestring.cpp index 52b7f55..f486aae 100644 --- a/bigscreen/widestring.cpp +++ b/bigscreen/widestring.cpp @@ -1,28 +1,52 @@ +#include +#include #include #include #include #include #include "widestring.h" -static iconv_t ucs4_iconv; +static iconv_t ucs4_iconv, ucs4_reverse_iconv; static bool iconv_initialized = false; +void ensure_iconv_initialized() +{ + if (iconv_initialized) { + return; + } +#if __BYTE_ORDER == __LITTLE_ENDIAN + ucs4_iconv = iconv_open("ucs-4le", "utf-8"); + ucs4_reverse_iconv = iconv_open("utf-8", "ucs-4le"); +#else + ucs4_iconv = iconv_open("ucs-4be", "utf-8"); + ucs4_reverse_iconv = iconv_open("utf-8", "ucs-4be"); +#endif + + iconv_initialized = true; +} + +widestring::widestring() +{ +} + widestring::widestring(const char *from) { *this = from; } -void widestring::operator= (const char *from) +widestring::widestring(const std::string &from) { - if (!iconv_initialized) { -#if __BYTE_ORDER == __LITTLE_ENDIAN - ucs4_iconv = iconv_open("ucs-4le", "utf-8"); -#else - ucs4_iconv = iconv_open("ucs-4be", "utf-8"); -#endif + *this = from.c_str(); +} - iconv_initialized = true; - } +widestring::widestring(const std::wstring &from) + : std::wstring(from) +{ +} + +void widestring::operator= (const char *from) +{ + ensure_iconv_initialized(); unsigned bytes = std::strlen(from); char *from_buf = strdup(from); @@ -51,9 +75,34 @@ void widestring::operator= (const char *from) delete[] to_buf; } -template<> -void pqxx::from_string(const char *from, widestring &to) +std::string widestring::to_utf8() const { - to = from; -} + ensure_iconv_initialized(); + + wchar_t *from_buf = wcsdup(c_str()); + size_t out_max_size = size() * 6; + char *to_buf = new char[out_max_size]; + + char *inptr = reinterpret_cast(from_buf), *outptr = to_buf; + + size_t in_left = size() * sizeof(wchar_t); + size_t out_left = out_max_size; + + size_t ret = iconv(ucs4_reverse_iconv, NULL, NULL, &outptr, &out_left); + if (ret == (size_t)(-1)) { + throw std::runtime_error("Error in iconv during initialization"); + } + ret = iconv(ucs4_reverse_iconv, &inptr, &in_left, &outptr, &out_left); + if (ret == (size_t)(-1)) { + perror("iconv"); + throw std::runtime_error("Error in iconv during conversion"); + } + + std::string utf8(to_buf, outptr); + + free(from_buf); + delete[] to_buf; + + return utf8; +}