summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2021-10-04 16:59:13 +0200
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-10-15 21:50:19 -0700
commitc8367df74639a399a2195a2a07ff7ac74b88d426 (patch)
treedd9febcec72643bec3138f47e43f9a5f364fde4f /AK
parent9c29e6cde7615cdb0dc8037dd67df422ecf064a6 (diff)
downloadserenity-c8367df74639a399a2195a2a07ff7ac74b88d426.zip
LibC: Implement wcrtomb
This function converts a single wide character into its multibyte representation (UTF-8 in our case). It is called from libc++'s `std::basic_ostream<wchar_t>::flush`, which gets called at program exit from a global destructor in order to flush `std::wcout`.
Diffstat (limited to 'AK')
-rw-r--r--AK/UnicodeUtils.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/AK/UnicodeUtils.h b/AK/UnicodeUtils.h
index e7211deaea..18ce9a7daa 100644
--- a/AK/UnicodeUtils.h
+++ b/AK/UnicodeUtils.h
@@ -17,4 +17,29 @@ constexpr bool is_unicode_control_code_point(u32 code_point)
Optional<StringView> get_unicode_control_code_point_alias(u32);
+template<typename Callback>
+[[nodiscard]] constexpr int code_point_to_utf8(u32 code_point, Callback callback)
+{
+ if (code_point <= 0x7f) {
+ callback((char)code_point);
+ return 1;
+ } else if (code_point <= 0x07ff) {
+ callback((char)(((code_point >> 6) & 0x1f) | 0xc0));
+ callback((char)(((code_point >> 0) & 0x3f) | 0x80));
+ return 2;
+ } else if (code_point <= 0xffff) {
+ callback((char)(((code_point >> 12) & 0x0f) | 0xe0));
+ callback((char)(((code_point >> 6) & 0x3f) | 0x80));
+ callback((char)(((code_point >> 0) & 0x3f) | 0x80));
+ return 3;
+ } else if (code_point <= 0x10ffff) {
+ callback((char)(((code_point >> 18) & 0x07) | 0xf0));
+ callback((char)(((code_point >> 12) & 0x3f) | 0x80));
+ callback((char)(((code_point >> 6) & 0x3f) | 0x80));
+ callback((char)(((code_point >> 0) & 0x3f) | 0x80));
+ return 4;
+ }
+ return -1;
+}
+
}