diff --git a/src/yycc/encoding/iconv.cpp b/src/yycc/encoding/iconv.cpp index 66407ec..c102934 100644 --- a/src/yycc/encoding/iconv.cpp +++ b/src/yycc/encoding/iconv.cpp @@ -75,8 +75,22 @@ namespace yycc::encoding::iconv { that_iconv_close(this->inner); } } + PrivToken(PrivToken&& rhs) : inner(rhs.inner) { + // Reset rhs inner + rhs.inner = INVALID_ICONV_TOKEN; + } + PrivToken& operator=(PrivToken&& rhs) { + // Free self first + if (this->inner != INVALID_ICONV_TOKEN) { + that_iconv_close(this->inner); + } + // Copy rhs inner and reset it. + this->inner = rhs.inner; + rhs.inner = INVALID_ICONV_TOKEN; + // Return self + return *this; + } YYCC_DELETE_COPY(PrivToken) - YYCC_DEFAULT_MOVE(PrivToken) bool is_valid() const { return this->inner != INVALID_ICONV_TOKEN; } that_iconv_t get_inner() const { return this->inner; } diff --git a/src/yycc/encoding/iconv.hpp b/src/yycc/encoding/iconv.hpp index 5d62d5c..b1a5790 100644 --- a/src/yycc/encoding/iconv.hpp +++ b/src/yycc/encoding/iconv.hpp @@ -40,9 +40,9 @@ namespace yycc::encoding::iconv { /// @private enum class ConvError { - InvalidCd, ///< Given token is invalid. - NullPointer, ///< Some of essential pointer in argument is nullptr. - InvalidMbSeq, ///< An invalid multibyte sequence has been encountered in the input. + InvalidCd, ///< Given token is invalid. + NullPointer, ///< Some of essential pointer in argument is nullptr. + InvalidMbSeq, ///< An invalid multibyte sequence has been encountered in the input. IncompleteMbSeq, ///< An incomplete multibyte sequence has been encountered in the input. }; @@ -50,6 +50,145 @@ namespace yycc::encoding::iconv { template using ConvResult = NS_YYCC_PATCH_EXPECTED::Expected; + // TODO: 为下列类添加注释时,指明static开头的是一次性使用的,适用于转换一两次结束。 + // 用实例类的适用于需要持续转换的。 + + // Char -> UTF8 + class CharToUtf8 { + public: + CharToUtf8(const CodeName& code_name); + ~CharToUtf8(); + YYCC_DELETE_COPY(CharToUtf8) + YYCC_DEFAULT_MOVE(CharToUtf8) + + public: + ConvResult priv_to_utf8(const std::string_view& src); + bool to_utf8(const std::string_view& src, NS_YYCC_STRING::u8string& dst); + NS_YYCC_STRING::u8string to_utf8(const std::string_view& src); + + private: + Token token; + }; + + // UTF8 -> Char + class Utf8ToChar { + public: + Utf8ToChar(const CodeName& code_name); + ~Utf8ToChar(); + YYCC_DELETE_COPY(Utf8ToChar) + YYCC_DEFAULT_MOVE(Utf8ToChar) + + public: + ConvResult priv_to_char(const NS_YYCC_STRING::u8string_view& src); + bool to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst); + std::string to_char(const NS_YYCC_STRING::u8string_view& src); + + private: + Token token; + }; + + // WChar -> Char + class WcharToChar { + public: + WcharToChar(const CodeName& code_name); + ~WcharToChar(); + YYCC_DELETE_COPY(WcharToChar) + YYCC_DEFAULT_MOVE(WcharToChar) + + public: + ConvResult priv_to_char(const std::wstring_view& src); + bool to_char(const std::wstring_view& src, std::string& dst); + std::string to_char(const std::wstring_view& src); + + private: + Token token; + }; + + // Char -> WChar + class CharToWchar { + public: + CharToWchar(const CodeName& code_name); + ~CharToWchar(); + YYCC_DELETE_COPY(CharToWchar) + YYCC_DEFAULT_MOVE(CharToWchar) + + public: + ConvResult priv_to_wchar(const std::string_view& src, const CodeName& code_name); + bool to_wchar(const std::string_view& src, std::wstring& dst, const CodeName& code_name); + std::wstring to_wchar(const std::string_view& src, const CodeName& code_name); + + private: + Token token; + }; + + // UTF8 -> UTF16 + class Utf8ToUtf16 { + public: + Utf8ToUtf16(); + ~Utf8ToUtf16(); + YYCC_DELETE_COPY(Utf8ToUtf16) + YYCC_DEFAULT_MOVE(Utf8ToUtf16) + + public: + ConvResult priv_to_utf16(const NS_YYCC_STRING::u8string_view& src); + bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst); + std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src); + + private: + Token token; + }; + + // UTF16 -> UTF8 + class Utf16ToUtf8 { + public: + Utf16ToUtf8(); + ~Utf16ToUtf8(); + YYCC_DELETE_COPY(Utf16ToUtf8) + YYCC_DEFAULT_MOVE(Utf16ToUtf8) + + public: + ConvResult priv_to_utf8(const std::u16string_view& src); + bool to_utf8(const std::u16string_view& src, NS_YYCC_STRING::u8string& dst); + NS_YYCC_STRING::u8string to_utf8(const std::u16string_view& src); + + private: + Token token; + }; + + // UTF8 -> UTF32 + class Utf8ToUtf32 { + public: + Utf8ToUtf32(); + ~Utf8ToUtf32(); + YYCC_DELETE_COPY(Utf8ToUtf32) + YYCC_DEFAULT_MOVE(Utf8ToUtf32) + + public: + ConvResult priv_to_utf32(const NS_YYCC_STRING::u8string_view& src); + bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst); + std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src); + + private: + Token token; + }; + + // UTF32 -> UTF8 + class Utf32ToUtf8 { + public: + Utf32ToUtf8(); + ~Utf32ToUtf8(); + YYCC_DELETE_COPY(Utf32ToUtf8) + YYCC_DEFAULT_MOVE(Utf32ToUtf8) + + public: + ConvResult priv_to_utf8(const std::u32string_view& src); + bool to_utf8(const std::u32string_view& src, NS_YYCC_STRING::u8string& dst); + NS_YYCC_STRING::u8string to_utf8(const std::u32string_view& src); + + private: + Token token; + }; + } // namespace yycc::encoding::iconv #undef NS_YYCC_PATCH_EXPECTED diff --git a/src/yycc/encoding/utf.hpp b/src/yycc/encoding/utf.hpp index ea9b2a6..8cac4cc 100644 --- a/src/yycc/encoding/utf.hpp +++ b/src/yycc/encoding/utf.hpp @@ -15,25 +15,21 @@ namespace yycc::encoding::utf { using ConvResult = NS_YYCC_PATCH_EXPECTED::Expected; // UTF8 -> UTF16 - ConvResult priv_to_utf16(const NS_YYCC_STRING::u8string_view& src); bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst); std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src); // UTF16 -> UTF8 - ConvResult priv_to_utf8(const std::u16string_view& src); bool to_utf8(const std::u16string_view& src, NS_YYCC_STRING::u8string& dst); NS_YYCC_STRING::u8string to_utf8(const std::u16string_view& src); // UTF8 -> UTF32 - ConvResult priv_to_utf32(const NS_YYCC_STRING::u8string_view& src); bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst); std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src); // UTF32 -> UTF8 - ConvResult priv_to_utf8(const std::u32string_view& src); bool to_utf8(const std::u32string_view& src, NS_YYCC_STRING::u8string& dst); NS_YYCC_STRING::u8string to_utf8(const std::u32string_view& src); diff --git a/src/yycc/encoding/windows.cpp b/src/yycc/encoding/windows.cpp index ccf9606..aaa62d4 100644 --- a/src/yycc/encoding/windows.cpp +++ b/src/yycc/encoding/windows.cpp @@ -241,9 +241,13 @@ namespace yycc::encoding::windows { #pragma endregion + // YYC MARK: + // The convertion between UTF is implemented by c16rtomb, c32rtomb, mbrtoc16 and mbrtoc32. + // These function is locale related in C++ standard, but in Microsoft STL, it's only for UTF8. + // So we can use them safely in Win32 environment. + #undef CONVFN_TYPE1 #undef CONVFN_TYPE2 -#undef CONVFCT_TYPE4 } // namespace yycc::encoding::windows diff --git a/src/yycc/encoding/windows.hpp b/src/yycc/encoding/windows.hpp index acba7d4..dfec5d8 100644 --- a/src/yycc/encoding/windows.hpp +++ b/src/yycc/encoding/windows.hpp @@ -65,6 +65,26 @@ namespace yycc::encoding::windows { bool to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst, CodePage code_page); std::string to_char(const NS_YYCC_STRING::u8string_view& src, CodePage code_page); + // UTF8 -> UTF16 + ConvResult priv_to_utf16(const NS_YYCC_STRING::u8string_view& src); + bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst); + std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src); + + // UTF16 -> UTF8 + ConvResult priv_to_utf8(const std::u16string_view& src); + bool to_utf8(const std::u16string_view& src, NS_YYCC_STRING::u8string& dst); + NS_YYCC_STRING::u8string to_utf8(const std::u16string_view& src); + + // UTF8 -> UTF32 + ConvResult priv_to_utf32(const NS_YYCC_STRING::u8string_view& src); + bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst); + std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src); + + // UTF32 -> UTF8 + ConvResult priv_to_utf8(const std::u32string_view& src); + bool to_utf8(const std::u32string_view& src, NS_YYCC_STRING::u8string& dst); + NS_YYCC_STRING::u8string to_utf8(const std::u32string_view& src); + } // namespace yycc::encoding::windows #undef NS_YYCC_PATCH_EXPECTED