#pragma once #include <luna/Result.h> #include <luna/Types.h> #include <stddef.h> class Utf8StringDecoder { public: Utf8StringDecoder(const char* str); usize byte_length() const { return m_byte_length; } Result<usize> code_points() const; // The caller must ensure that 'buf' is at least code_points() + a NULL wide. Result<usize> decode(wchar_t* buf) const; Result<usize> decode(wchar_t* buf, usize max) const; private: const char* m_str; usize m_byte_length; }; class Utf8StringEncoder { public: Utf8StringEncoder(const wchar_t* str); usize code_points() const { return m_code_points; } Result<usize> byte_length() const; // The caller must ensure that 'buf' is at least byte_length() + a NULL wide. Result<usize> encode(char* buf) const; Result<usize> encode(char* buf, usize max) const; private: const wchar_t* m_str; usize m_code_points; }; class Utf8StateDecoder { public: Utf8StateDecoder(); Result<bool> feed(char c); Result<wchar_t> extract(); void reset(); private: char m_state[4]; usize m_state_len = 0; usize m_state_index = 0; wchar_t m_decoded_character; bool m_has_character_ready { false }; }; class Utf8Encoder { public: // Does not null-terminate. Returns the number of bytes written. Result<usize> encode(wchar_t c, char buf[4]); };