From b8abd466ddf351dd6c53d84be1f87b4d185ba3a0 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Mon, 23 Jan 2017 21:40:09 -1000 Subject: [PATCH] char16_t formatting support --- hecl/extern/athena | 2 +- hecl/include/hecl/hecl.hpp | 3 +++ hecl/lib/WideStringConvert.cpp | 38 ++++++++++++++++++++++++++++++++++ hecl/lib/hecl.cpp | 14 +++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/hecl/extern/athena b/hecl/extern/athena index 483870850..dd8b60f77 160000 --- a/hecl/extern/athena +++ b/hecl/extern/athena @@ -1 +1 @@ -Subproject commit 483870850c24956d9549bad5149a97e80de42f2a +Subproject commit dd8b60f779a97281ebf9f7778c4c0365fdc54457 diff --git a/hecl/include/hecl/hecl.hpp b/hecl/include/hecl/hecl.hpp index f03056e13..4906c248b 100644 --- a/hecl/include/hecl/hecl.hpp +++ b/hecl/include/hecl/hecl.hpp @@ -52,7 +52,9 @@ extern logvisor::Module LogModule; #endif std::string WideToUTF8(const std::wstring& src); +std::string Char16ToUTF8(const std::u16string& src); std::wstring UTF8ToWide(const std::string& src); +std::u16string UTF8ToChar16(const std::string& src); /* humanize_number port from FreeBSD's libutil */ enum class HNFlags @@ -424,6 +426,7 @@ std::string Format(const char* format, ...); std::wstring WideFormat(const wchar_t* format, ...); +std::u16string Char16Format(const wchar_t* format, ...); static inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz) { diff --git a/hecl/lib/WideStringConvert.cpp b/hecl/lib/WideStringConvert.cpp index cea1e433d..870ad0637 100644 --- a/hecl/lib/WideStringConvert.cpp +++ b/hecl/lib/WideStringConvert.cpp @@ -22,6 +22,24 @@ std::string WideToUTF8(const std::wstring& src) return retval; } +std::string Char16ToUTF8(const std::u16string& src) +{ + std::string retval; + retval.reserve(src.length()); + for (char16_t ch : src) + { + utf8proc_uint8_t mb[4]; + utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(ch), mb); + if (c < 0) + { + LogModule.report(logvisor::Warning, "invalid UTF-8 character while encoding"); + return retval; + } + retval.append(reinterpret_cast(mb), c); + } + return retval; +} + std::wstring UTF8ToWide(const std::string& src) { std::wstring retval; @@ -42,4 +60,24 @@ std::wstring UTF8ToWide(const std::string& src) return retval; } +std::u16string UTF8ToChar16(const std::string& src) +{ + std::u16string retval; + retval.reserve(src.length()); + const utf8proc_uint8_t* buf = reinterpret_cast(src.c_str()); + while (*buf) + { + utf8proc_int32_t wc; + utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc); + if (len < 0) + { + LogModule.report(logvisor::Warning, "invalid UTF-8 character while decoding"); + return retval; + } + buf += len; + retval += char16_t(wc); + } + return retval; +} + } diff --git a/hecl/lib/hecl.cpp b/hecl/lib/hecl.cpp index e19c5f07c..8f26d98f8 100644 --- a/hecl/lib/hecl.cpp +++ b/hecl/lib/hecl.cpp @@ -65,6 +65,20 @@ std::wstring WideFormat(const wchar_t* format, ...) return std::wstring(resultBuf, printSz); } +std::u16string Char16Format(const wchar_t* format, ...) +{ + wchar_t resultBuf[FORMAT_BUF_SZ]; + va_list va; + va_start(va, format); + int printSz = vswprintf(resultBuf, FORMAT_BUF_SZ, format, va); + va_end(va); + std::u16string res; + res.reserve(printSz); + for (size_t i=0 ; i