fix: change the behavior of printf in string op.
- add compiler hint for checking the arguments of printf. - change the return value of printf. from std::expected to normal value. use C++ exception to indicate error. * the error of printf usually caused by programmer. so it can be found when testing program. * so i use std::logic_error to indicate this and programmer should fix this before releasing program. - change the use of encoding convertion. for those cases that convertion must be safe, we unwrap it directly.
This commit is contained in:
@@ -130,21 +130,15 @@ namespace yycc::windows::dialog {
|
||||
// build new Windows oriented string vector
|
||||
for (const auto& item : m_Filters) {
|
||||
// convert name to wchar
|
||||
auto win_name = ENC::to_wchar(item.first);
|
||||
if (!win_name.has_value()) {
|
||||
return std::unexpected(DialogError::BadEncoding);
|
||||
}
|
||||
auto win_name = ENC::to_wchar(item.first).value();
|
||||
|
||||
// join pattern string and convert to wchar
|
||||
const auto& modes = item.second;
|
||||
auto joined_modes = OP::join(modes.begin(), modes.end(), u8";");
|
||||
auto win_modes = ENC::to_wchar(joined_modes);
|
||||
if (!win_modes.has_value()) {
|
||||
return std::unexpected(DialogError::BadEncoding);
|
||||
}
|
||||
auto win_modes = ENC::to_wchar(joined_modes).value();
|
||||
|
||||
// append this pair
|
||||
rv.m_WinFilters.emplace_back(std::make_pair(win_name.value(), win_modes.value()));
|
||||
rv.m_WinFilters.emplace_back(std::make_pair(win_name, win_modes));
|
||||
}
|
||||
|
||||
// update data struct
|
||||
@@ -305,28 +299,21 @@ namespace yycc::windows::dialog {
|
||||
|
||||
// build title and init file name
|
||||
if (m_Title.has_value()) {
|
||||
auto win_title = ENC::to_wchar(m_Title.value());
|
||||
if (!win_title.has_value()) return std::unexpected(DialogError::BadEncoding);
|
||||
else rv.m_WinTitle = win_title.value();
|
||||
rv.m_WinTitle = ENC::to_wchar(m_Title.value()).value();
|
||||
} else rv.m_WinTitle = std::nullopt;
|
||||
if (m_InitFileName.has_value()) {
|
||||
auto win_init_file_name = ENC::to_wchar(m_InitFileName.value());
|
||||
if (!win_init_file_name.has_value()) return std::unexpected(DialogError::BadEncoding);
|
||||
else rv.m_WinInitFileName = win_init_file_name.value();
|
||||
rv.m_WinInitFileName = ENC::to_wchar(m_InitFileName.value()).value();
|
||||
} else rv.m_WinInitFileName = std::nullopt;
|
||||
|
||||
// fetch init directory
|
||||
if (m_InitDirectory.has_value()) {
|
||||
// convert to wchar path
|
||||
auto w_init_dir = ENC::to_wchar(m_InitDirectory.value());
|
||||
if (!w_init_dir.has_value()) {
|
||||
return std::unexpected(DialogError::BadEncoding);
|
||||
}
|
||||
auto w_init_dir = ENC::to_wchar(m_InitDirectory.value()).value();
|
||||
|
||||
// fetch IShellItem*
|
||||
// Ref: https://stackoverflow.com/questions/76306324/how-to-set-default-folder-for-ifileopendialog-interface
|
||||
IShellItem* init_directory = NULL;
|
||||
HRESULT hr = SHCreateItemFromParsingName(w_init_dir.value().c_str(), NULL, IID_PPV_ARGS(&init_directory));
|
||||
HRESULT hr = SHCreateItemFromParsingName(w_init_dir.c_str(), NULL, IID_PPV_ARGS(&init_directory));
|
||||
if (FAILED(hr)) return std::unexpected(DialogError::NoSuchDir);
|
||||
|
||||
// assign IShellItem*
|
||||
@@ -378,7 +365,7 @@ namespace yycc::windows::dialog {
|
||||
WINCOM::SmartLPWSTR display_name(display_name_ptr);
|
||||
|
||||
// convert result and return
|
||||
return ENC::to_utf8(display_name.get()).transform_error([](auto err) { return DialogError::BadEncoding; });
|
||||
return ENC::to_utf8(display_name.get()).value();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace yycc::windows::dialog {
|
||||
|
||||
/// @brief The error occurs in this module.
|
||||
enum class DialogError {
|
||||
BadEncoding, ///< Error occurs when perform encoding convertion.
|
||||
TooManyFilters, ///< The size of file filters list is too large for Windows.
|
||||
IndexOverflow, ///< Default filter index is too large for Windows.
|
||||
EmptyFilters, ///< File filters is empty when picking file.
|
||||
@@ -310,7 +309,7 @@ namespace yycc::windows::dialog {
|
||||
*/
|
||||
DialogResult<DialogOutcome<std::u8string>> open_folder(const FileDialog& params);
|
||||
|
||||
}
|
||||
} // namespace yycc::windows::dialog
|
||||
|
||||
#undef NS_YYCC_WINDOWS_COM
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace yycc::windows::winfct {
|
||||
(LPCWSTR) get_current_module,
|
||||
&hModule);
|
||||
if (rv) return hModule;
|
||||
else return std::unexpected(WinFctError::Backend);
|
||||
else return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
WinFctResult<std::u8string> get_temp_directory() {
|
||||
@@ -33,7 +33,7 @@ namespace yycc::windows::winfct {
|
||||
while (true) {
|
||||
if ((expected_size = ::GetTempPathW(static_cast<DWORD>(wpath.size()), wpath.data())) == 0) {
|
||||
// failed, return
|
||||
return std::unexpected(WinFctError::Backend);
|
||||
return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
if (expected_size > static_cast<DWORD>(wpath.size())) {
|
||||
@@ -47,7 +47,7 @@ namespace yycc::windows::winfct {
|
||||
}
|
||||
|
||||
// convert to utf8 and return
|
||||
return ENC::to_utf8(wpath).transform_error([](auto err) { return WinFctError::Encoding; });
|
||||
return ENC::to_utf8(wpath).value();
|
||||
}
|
||||
|
||||
WinFctResult<std::u8string> get_module_file_name(HINSTANCE hModule) {
|
||||
@@ -58,7 +58,7 @@ namespace yycc::windows::winfct {
|
||||
while (true) {
|
||||
if ((copied_size = ::GetModuleFileNameW(hModule, wpath.data(), static_cast<DWORD>(wpath.size()))) == 0) {
|
||||
// failed, return
|
||||
return std::unexpected(WinFctError::Backend);
|
||||
return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
// check insufficient buffer
|
||||
@@ -73,7 +73,7 @@ namespace yycc::windows::winfct {
|
||||
}
|
||||
|
||||
// convert to utf8 and return
|
||||
return ENC::to_utf8(wpath).transform_error([](auto err) { return WinFctError::Encoding; });
|
||||
return ENC::to_utf8(wpath).value();
|
||||
}
|
||||
|
||||
bool is_valid_code_page(UINT code_page) {
|
||||
@@ -82,41 +82,32 @@ namespace yycc::windows::winfct {
|
||||
}
|
||||
|
||||
WinFctResult<void> copy_file(const std::u8string_view& lpExistingFileName, const std::u8string_view& lpNewFileName, BOOL bFailIfExists) {
|
||||
auto wExistingFileName = ENC::to_wchar(lpExistingFileName);
|
||||
auto wNewFileName = ENC::to_wchar(lpNewFileName);
|
||||
if (!(wExistingFileName.has_value() && wNewFileName.has_value())) {
|
||||
return std::unexpected(WinFctError::Encoding);
|
||||
}
|
||||
auto wExistingFileName = ENC::to_wchar(lpExistingFileName).value();
|
||||
auto wNewFileName = ENC::to_wchar(lpNewFileName).value();
|
||||
|
||||
if (!::CopyFileW(wExistingFileName.value().c_str(), wNewFileName.value().c_str(), bFailIfExists)) {
|
||||
return std::unexpected(WinFctError::Backend);
|
||||
if (!::CopyFileW(wExistingFileName.c_str(), wNewFileName.c_str(), bFailIfExists)) {
|
||||
return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
WinFctResult<void> move_file(const std::u8string_view& lpExistingFileName, const std::u8string_view& lpNewFileName) {
|
||||
auto wExistingFileName = ENC::to_wchar(lpExistingFileName);
|
||||
auto wNewFileName = ENC::to_wchar(lpNewFileName);
|
||||
if (!(wExistingFileName.has_value() && wNewFileName.has_value())) {
|
||||
return std::unexpected(WinFctError::Encoding);
|
||||
}
|
||||
auto wExistingFileName = ENC::to_wchar(lpExistingFileName).value();
|
||||
auto wNewFileName = ENC::to_wchar(lpNewFileName).value();
|
||||
|
||||
if (!::MoveFileW(wExistingFileName.value().c_str(), wNewFileName.value().c_str())) {
|
||||
return std::unexpected(WinFctError::Backend);
|
||||
if (!::MoveFileW(wExistingFileName.c_str(), wNewFileName.c_str())) {
|
||||
return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
WinFctResult<void> delete_file(const std::u8string_view& lpFileName) {
|
||||
auto wFileName = ENC::to_wchar(lpFileName);
|
||||
if (!wFileName.has_value()) {
|
||||
return std::unexpected(WinFctError::Encoding);
|
||||
}
|
||||
auto wFileName = ENC::to_wchar(lpFileName).value();
|
||||
|
||||
if (!::DeleteFileW(wFileName.value().c_str())) {
|
||||
return std::unexpected(WinFctError::Backend);
|
||||
if (!::DeleteFileW(wFileName.c_str())) {
|
||||
return std::unexpected(WinFctError::Win32);
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -144,11 +135,11 @@ namespace yycc::windows::winfct {
|
||||
// fetch path
|
||||
LPWSTR raw_known_path;
|
||||
HRESULT hr = SHGetKnownFolderPath(*pId, KF_FLAG_CREATE, NULL, &raw_known_path);
|
||||
if (FAILED(hr)) return std::unexpected(WinFctError::Backend);
|
||||
if (FAILED(hr)) return std::unexpected(WinFctError::Win32);
|
||||
COM::SmartLPWSTR known_path(raw_known_path);
|
||||
|
||||
// convert to utf8 and return
|
||||
return ENC::to_utf8(known_path.get()).transform_error([](auto err) { return WinFctError::Encoding; });
|
||||
return ENC::to_utf8(known_path.get()).value();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,8 +15,7 @@ namespace yycc::windows::winfct {
|
||||
|
||||
/// @brief All errors occur in this module.
|
||||
enum class WinFctError {
|
||||
Backend, ///< Error occurs when calling Win32 functions.
|
||||
Encoding, ///< Can not perform encoding convertion.
|
||||
Win32, ///< Error occurs when calling Win32 functions.
|
||||
NoCom, ///< No COM environment.
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user