doc: update comments of code.
- add lost testbench for wchar encoding convertion. - update code documentation.
This commit is contained in:
parent
77b6f439f7
commit
f153f9bc22
|
@ -12,16 +12,16 @@
|
||||||
/**
|
/**
|
||||||
* @brief COM fucntions related namespace.
|
* @brief COM fucntions related namespace.
|
||||||
* @details
|
* @details
|
||||||
* This namespace is Windows specific and it will disappear on other platforms.
|
* This namespace is Windows specific and is unavailable on other platforms.
|
||||||
*
|
*
|
||||||
* This namespace contain a COM Guard which make sure COM was initialized in current module when loading current module.
|
* This namespace contain a COM Guard which make sure COM was initialized in current module when loading current module.
|
||||||
* It is essential because all calling to COM functions should be under the premise that COM has been initialized.
|
* It is essential because all calling to COM functions should be under the premise that COM has been initialized.
|
||||||
* This guard also will uninitialize COM when unloading this module.
|
* This guard also will uninitialize COM when unloading this module.
|
||||||
*
|
*
|
||||||
* This namespace also provided various memory-safe types for interacting with COM functions.
|
* This namespace also provided various memory-safe types for interacting with COM functions.
|
||||||
* Although Microsoft also has similar smart pointer called CComPtr.
|
* Although Microsoft also has similar smart pointer called \c CComPtr.
|
||||||
* But this library is eager to hide all Microsoft-related functions calling.
|
* But this library is eager to hide all Microsoft-related functions calling.
|
||||||
* Using CComPtr is not corresponding with the philosophy of this library.
|
* Using \c CComPtr is not corresponding with the philosophy of this library.
|
||||||
* So these std-based smart pointer type were created.
|
* So these std-based smart pointer type were created.
|
||||||
*
|
*
|
||||||
* This namespace is used by internal functions as intended.
|
* This namespace is used by internal functions as intended.
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace YYCC::EncodingHelper {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename _TChar, std::enable_if_t<std::is_same_v<_TChar, char16_t> || std::is_same_v<_TChar, char32_t>, int> = 0>
|
template<typename _TChar, std::enable_if_t<std::is_same_v<_TChar, char16_t> || std::is_same_v<_TChar, char32_t>, int> = 0>
|
||||||
bool UTF8ToUTFOther(const char* src, std::basic_string<_TChar>& dest) {
|
static bool UTF8ToUTFOther(const char* src, std::basic_string<_TChar>& dest) {
|
||||||
// Reference:
|
// Reference:
|
||||||
// https://zh.cppreference.com/w/cpp/string/multibyte/mbrtoc32
|
// https://zh.cppreference.com/w/cpp/string/multibyte/mbrtoc32
|
||||||
// https://zh.cppreference.com/w/cpp/string/multibyte/mbrtoc16
|
// https://zh.cppreference.com/w/cpp/string/multibyte/mbrtoc16
|
||||||
|
@ -146,7 +146,7 @@ namespace YYCC::EncodingHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _TChar, std::enable_if_t<std::is_same_v<_TChar, char16_t> || std::is_same_v<_TChar, char32_t>, int> = 0>
|
template<typename _TChar, std::enable_if_t<std::is_same_v<_TChar, char16_t> || std::is_same_v<_TChar, char32_t>, int> = 0>
|
||||||
bool UTFOtherToUTF8(const _TChar* src, std::string& dest) {
|
static bool UTFOtherToUTF8(const _TChar* src, std::string& dest) {
|
||||||
// Reference:
|
// Reference:
|
||||||
// https://zh.cppreference.com/w/cpp/string/multibyte/c32rtomb
|
// https://zh.cppreference.com/w/cpp/string/multibyte/c32rtomb
|
||||||
// https://zh.cppreference.com/w/cpp/string/multibyte/c16rtomb
|
// https://zh.cppreference.com/w/cpp/string/multibyte/c16rtomb
|
||||||
|
|
|
@ -9,6 +9,45 @@
|
||||||
#include "WinImportSuffix.hpp"
|
#include "WinImportSuffix.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The namespace handling encoding issues.
|
||||||
|
* @details
|
||||||
|
* \par Windows Encoding Convertion
|
||||||
|
* This namespace provides the convertion between wchar_t, UTF8 and code-page-based string:
|
||||||
|
* The function name has following format: \c AAAToBBB.
|
||||||
|
* AAA is the source string and BBB is target string.
|
||||||
|
* AAA and BBB has following possible value:
|
||||||
|
* \li \c Char: Code-page-based string. Usually it will add a code page parameter for function to get the code page of this string. For code page, please see Microsoft document.
|
||||||
|
* \li \c UTF8: UTF8 string.
|
||||||
|
* \li \c Wchar: wchar_t string.
|
||||||
|
* \par
|
||||||
|
* For example: \c WcharToUTF8 will perform the convertion from wchar_t to UTF8,
|
||||||
|
* and \c CharToChar will perform the convertion between 2 code-page-based string and caller can specify individual code page for these 2 string.
|
||||||
|
* \par
|
||||||
|
* These functions are Windows specific and are unavailable on other platforms.
|
||||||
|
* Becasue Windows use wchar_t string as its function arguments for globalization, and this library use UTF8 everywhere.
|
||||||
|
* So it should have a bidirectional way to do convertion between wchar_t string and UTF8 string.
|
||||||
|
*
|
||||||
|
* \par UTF32, UTF16 and UTF8 Convertion
|
||||||
|
* This namespace also provide the convertion among UTF32, UTF16 and UTF8.
|
||||||
|
* These convertion functions are suit for all platforms, not Windows oriented.
|
||||||
|
* \par
|
||||||
|
* Due to implementation, this library assume all non-Windows system use UTF8 as their C locale.
|
||||||
|
* Otherwise these functions will produce wrong result.
|
||||||
|
*
|
||||||
|
* \par Function Parameters
|
||||||
|
* We provide these encoding convertion functions with following 2 types:
|
||||||
|
* \li Function returns \c bool and its parameter order source string pointer and a corresponding \c std::basic_string container for receiving result.
|
||||||
|
* \li Function returns corresponding \c std::basic_string result, and its parameter only order source string pointer.
|
||||||
|
* \par
|
||||||
|
* For these 2 declarations, both of them will not throw any exception and do not accept nullptr as source string.
|
||||||
|
* The only difference is that the way to indicate convertion error.
|
||||||
|
* \par
|
||||||
|
* First declaration will return false to indicate there is an error when doing convertion. Please note that the content of string container passing in may still be changed!
|
||||||
|
* Last declaration will return empty string to indicate error. Please note if you pass empty string in, they still will output empty string but it doesn't mean an error.
|
||||||
|
* So last declaration is used in the scenario that we don't care whether the convertion success did. For example, output something to console.
|
||||||
|
*
|
||||||
|
*/
|
||||||
namespace YYCC::EncodingHelper {
|
namespace YYCC::EncodingHelper {
|
||||||
|
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
|
|
@ -2,6 +2,16 @@
|
||||||
#include "YYCCInternal.hpp"
|
#include "YYCCInternal.hpp"
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Windows specific unhandled exception processor.
|
||||||
|
* @details
|
||||||
|
* This namespace is Windows specific. On other platforms, the whole namespace is unavailable.
|
||||||
|
*
|
||||||
|
* This namespace allow user register unhandled exception handler on Windows
|
||||||
|
* to output error log into \c stderr and log file, and generate coredump if possible.
|
||||||
|
* This is useful for bug tracing on Windows, especially most Windows user are naive and don't know how to report bug.
|
||||||
|
*
|
||||||
|
*/
|
||||||
namespace YYCC::ExceptionHelper {
|
namespace YYCC::ExceptionHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +25,6 @@ namespace YYCC::ExceptionHelper {
|
||||||
* in temp folder (for convenient debugging of developer when reporting bugs) if it can.
|
* in temp folder (for convenient debugging of developer when reporting bugs) if it can.
|
||||||
*
|
*
|
||||||
* This function usually is called at the start of program.
|
* This function usually is called at the start of program.
|
||||||
* @remarks This function is Windows only.
|
|
||||||
*/
|
*/
|
||||||
void Register();
|
void Register();
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +36,6 @@ namespace YYCC::ExceptionHelper {
|
||||||
* You must call this function if you have called Register() before.
|
* You must call this function if you have called Register() before.
|
||||||
*
|
*
|
||||||
* This function usually is called at the end of program.
|
* This function usually is called at the end of program.
|
||||||
* @remarks This function is Windows only.
|
|
||||||
*/
|
*/
|
||||||
void Unregister();
|
void Unregister();
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
* @brief The helper providing assistance to Win32 functions.
|
* @brief The helper providing assistance to Win32 functions.
|
||||||
* @details
|
* @details
|
||||||
* This helper is Windows specific.
|
* This helper is Windows specific.
|
||||||
* If current environment is not Windows,
|
* If current environment is not Windows, the whole namespace will be unavailable.
|
||||||
* the whole namespace will disappear.
|
|
||||||
*/
|
*/
|
||||||
namespace YYCC::WinFctHelper {
|
namespace YYCC::WinFctHelper {
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
namespace Console = YYCC::ConsoleHelper;
|
namespace Console = YYCC::ConsoleHelper;
|
||||||
|
|
||||||
namespace YYCCTestbench {
|
namespace YYCCTestbench {
|
||||||
#pragma region UNICODE Test Data
|
|
||||||
|
#pragma region Unicode Test Data
|
||||||
|
|
||||||
// UNICODE Test Strings
|
// UNICODE Test Strings
|
||||||
// Ref: https://stackoverflow.com/questions/478201/how-to-test-an-application-for-correct-encoding-e-g-utf-8
|
// Ref: https://stackoverflow.com/questions/478201/how-to-test-an-application-for-correct-encoding-e-g-utf-8
|
||||||
|
@ -25,6 +26,7 @@ namespace YYCCTestbench {
|
||||||
#define CPP_U8_LITERAL(strl) strl
|
#define CPP_U8_LITERAL(strl) strl
|
||||||
#define CPP_U16_LITERAL(strl) CONCAT(u, strl)
|
#define CPP_U16_LITERAL(strl) CONCAT(u, strl)
|
||||||
#define CPP_U32_LITERAL(strl) CONCAT(U, strl)
|
#define CPP_U32_LITERAL(strl) CONCAT(U, strl)
|
||||||
|
#define CPP_WSTR_LITERAL(strl) CONCAT(L, strl)
|
||||||
|
|
||||||
static std::vector<std::string> c_UTF8TestStrTable {
|
static std::vector<std::string> c_UTF8TestStrTable {
|
||||||
CPP_U8_LITERAL(TEST_UNICODE_STR_JAPAN),
|
CPP_U8_LITERAL(TEST_UNICODE_STR_JAPAN),
|
||||||
|
@ -40,6 +42,20 @@ namespace YYCCTestbench {
|
||||||
CPP_U8_LITERAL(TEST_UNICODE_STR_MATHMATICS),
|
CPP_U8_LITERAL(TEST_UNICODE_STR_MATHMATICS),
|
||||||
CPP_U8_LITERAL(TEST_UNICODE_STR_EMOJI),
|
CPP_U8_LITERAL(TEST_UNICODE_STR_EMOJI),
|
||||||
};
|
};
|
||||||
|
static std::vector<std::wstring> c_WStrTestStrTable {
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_JAPAN),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_CHINA),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_KOREA),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_ISRAEL),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_EGYPT),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_GREECE),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_RUSSIA),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_THAILAND),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_FRANCE),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_SPAIN),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_MATHMATICS),
|
||||||
|
CPP_WSTR_LITERAL(TEST_UNICODE_STR_EMOJI),
|
||||||
|
};
|
||||||
static std::vector<std::u16string> c_UTF16TestStrTable {
|
static std::vector<std::u16string> c_UTF16TestStrTable {
|
||||||
CPP_U16_LITERAL(TEST_UNICODE_STR_JAPAN),
|
CPP_U16_LITERAL(TEST_UNICODE_STR_JAPAN),
|
||||||
CPP_U16_LITERAL(TEST_UNICODE_STR_CHINA),
|
CPP_U16_LITERAL(TEST_UNICODE_STR_CHINA),
|
||||||
|
@ -69,6 +85,7 @@ namespace YYCCTestbench {
|
||||||
CPP_U32_LITERAL(TEST_UNICODE_STR_EMOJI),
|
CPP_U32_LITERAL(TEST_UNICODE_STR_EMOJI),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef CPP_WSTR_LITERAL
|
||||||
#undef CPP_U32_LITERAL
|
#undef CPP_U32_LITERAL
|
||||||
#undef CPP_U16_LITERAL
|
#undef CPP_U16_LITERAL
|
||||||
#undef CPP_U8_LITERAL
|
#undef CPP_U8_LITERAL
|
||||||
|
@ -76,9 +93,6 @@ namespace YYCCTestbench {
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void Assert(bool condition, const char* description) {
|
static void Assert(bool condition, const char* description) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
Console::FormatLine(YYCC_COLOR_LIGHT_GREEN("OK: %s"), description);
|
Console::FormatLine(YYCC_COLOR_LIGHT_GREEN("OK: %s"), description);
|
||||||
|
@ -126,9 +140,10 @@ namespace YYCCTestbench {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EncodingTestbench() {
|
static void EncodingTestbench() {
|
||||||
|
// get test tuple size
|
||||||
|
size_t count = c_UTF8TestStrTable.size();
|
||||||
|
|
||||||
// check the convertion between given string
|
// check the convertion between given string
|
||||||
size_t count = c_UTF8TestStrTable.size();
|
|
||||||
for (size_t i = 0u; i < count; ++i) {
|
for (size_t i = 0u; i < count; ++i) {
|
||||||
// get item
|
// get item
|
||||||
const auto& u8str = c_UTF8TestStrTable[i];
|
const auto& u8str = c_UTF8TestStrTable[i];
|
||||||
|
@ -141,17 +156,26 @@ namespace YYCCTestbench {
|
||||||
std::u32string u32cache;
|
std::u32string u32cache;
|
||||||
|
|
||||||
// do convertion check
|
// do convertion check
|
||||||
Assert(YYCC::EncodingHelper::UTF8ToUTF16(u8str.c_str(), u16cache), "YYCC::EncodingHelper::UTF8ToUTF16");
|
Assert(YYCC::EncodingHelper::UTF8ToUTF16(u8str.c_str(), u16cache) && u16cache == u16str, "YYCC::EncodingHelper::UTF8ToUTF16");
|
||||||
Assert(u16cache == u16str, "YYCC::EncodingHelper::UTF8ToUTF16");
|
Assert(YYCC::EncodingHelper::UTF8ToUTF32(u8str.c_str(), u32cache) && u32cache == u32str, "YYCC::EncodingHelper::UTF8ToUTF32");
|
||||||
|
|
||||||
Assert(YYCC::EncodingHelper::UTF8ToUTF32(u8str.c_str(), u32cache), "YYCC::EncodingHelper::UTF8ToUTF32");
|
Assert(YYCC::EncodingHelper::UTF16ToUTF8(u16str.c_str(), u8cache) && u8cache == u8str, "YYCC::EncodingHelper::UTF16ToUTF8");
|
||||||
Assert(u32cache == u32str, "YYCC::EncodingHelper::UTF8ToUTF32");
|
Assert(YYCC::EncodingHelper::UTF32ToUTF8(u32str.c_str(), u8cache) && u8cache == u8str, "YYCC::EncodingHelper::UTF32ToUTF8");
|
||||||
|
}
|
||||||
|
|
||||||
Assert(YYCC::EncodingHelper::UTF16ToUTF8(u16str.c_str(), u8cache), "YYCC::EncodingHelper::UTF16ToUTF8");
|
// check wstring convertion on windows
|
||||||
Assert(u8cache == u8str, "YYCC::EncodingHelper::UTF16ToUTF8");
|
for (size_t i = 0u; i < count; ++i) {
|
||||||
|
// get item
|
||||||
|
const auto& u8str = c_UTF8TestStrTable[i];
|
||||||
|
const auto& wstr = c_WStrTestStrTable[i];
|
||||||
|
|
||||||
Assert(YYCC::EncodingHelper::UTF32ToUTF8(u32str.c_str(), u8cache), "YYCC::EncodingHelper::UTF32ToUTF8");
|
// create cache variables
|
||||||
Assert(u8cache == u8str, "YYCC::EncodingHelper::UTF32ToUTF8");
|
std::string u8cache;
|
||||||
|
std::wstring wcache;
|
||||||
|
|
||||||
|
// do convertion check
|
||||||
|
Assert(YYCC::EncodingHelper::UTF8ToWchar(u8str.c_str(), wcache) && wcache == wstr, "YYCC::EncodingHelper::UTF8ToWchar");
|
||||||
|
Assert(YYCC::EncodingHelper::WcharToUTF8(wstr.c_str(), u8cache) && u8cache == u8str, "YYCC::EncodingHelper::WcharToUTF8");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user