From 73fa772201df24fcf5806b927bb0a2940c7772b3 Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Tue, 18 Jul 2023 14:13:43 +0800 Subject: [PATCH] optimize file searching --- sdk/hginclude/utils.cpp | 88 ++++++++++++++++++++++++++++++++++------ sdk/hginclude/utils.h | 2 + twain/ds/huagaods.cpp | 6 ++- twain/ds/sane_helper.cpp | 2 +- twain/ds/scanner.cpp | 32 +++++++-------- 5 files changed, 99 insertions(+), 31 deletions(-) diff --git a/sdk/hginclude/utils.cpp b/sdk/hginclude/utils.cpp index 79299f8..ed94974 100644 --- a/sdk/hginclude/utils.cpp +++ b/sdk/hginclude/utils.cpp @@ -390,15 +390,26 @@ log_cls* log_cls::inst_ = NULL; namespace utils { + typedef struct _match_part + { + std::string pattern; + std::string found; + bool(*match)(const char*, const char*); + }MATCHPART; + + static bool find_sub_str(const char* text, const char* pattern) + { + return strstr(text, pattern) != nullptr; + } static bool STDCALL match_part_filename(const char* path_name, bool dir, void* param) { - std::string* partn = (std::string*)param; - + MATCHPART* partn = (MATCHPART*)param; + if (!dir) { - if (partn[0].empty()) + if (partn->pattern.empty()) { - partn[1] = path_name; + partn->found = path_name; } else { @@ -408,8 +419,9 @@ namespace utils std::string n(name); to_lower(n); - if (strstr(n.c_str(), partn[0].c_str())) - partn[1] = path_name; + // if (strstr(n.c_str(), partn[0].c_str())) + if(partn->match(n.c_str(), partn->pattern.c_str())) + partn->found = path_name; else dir = true; } @@ -603,9 +615,11 @@ namespace utils } std::string get_module_full_path(const char* part_name/*nullptr to get main-pe/first module's full path*/) { - std::string file[] = { part_name ? part_name : "", ""}; + MATCHPART file = {part_name ? part_name : "", "", find_sub_str}; - to_lower(file[0]); + to_lower(file.pattern); + if(file.pattern.find("*") != std::string::npos) + file.match = is_match_pattern; #if OS_WIN if (part_name && *part_name) @@ -623,7 +637,7 @@ namespace utils char path[256] = { 0 }; GetModuleFileNameA(pei.hModule, path, _countof(path) - 1); - if (!match_part_filename(path, false, (void*)file)) + if (!match_part_filename(path, false, (void*)&file)) break; pei.dwSize = sizeof(pei); } while (Module32NextW(h, &pei)); @@ -636,15 +650,26 @@ namespace utils char path[256] = { 0 }; GetModuleFileNameA(NULL, path, _countof(path) - 1); - file[1] = path; + file.found = path; } #else char path[128] = { 0 }; sprintf(path, "/proc/%u/map_files/", getpid()); - enum_file(path, false, match_part_filename, (void*)file); + enum_file(path, false, match_part_filename, (void*)&file); #endif - return std::move(file[1]); + return std::move(file.found); + } + std::string find_file(const char* root_dir, const char* part_name, bool recursive) + { + MATCHPART file = {part_name ? part_name : "", "", find_sub_str}; + + to_lower(file.pattern); + if(file.pattern.find("*") != std::string::npos) + file.match = is_match_pattern; + enum_file(root_dir, recursive, match_part_filename, (void*)&file); + + return std::move(file.found); } std::string target_file_from_link(const char* lnk_file) { @@ -723,6 +748,45 @@ namespace utils return err; } + bool is_match_pattern(const char* text, const char* pattern) + { + int str_ind = 0, pattern_ind = 0, star = -1, m = 0, + str_len = strlen(text), + patt_len = strlen(pattern); + bool ok = true; + + while (str_ind < str_len) + { + if (pattern_ind < patt_len && (text[str_ind] == pattern[pattern_ind] || pattern[pattern_ind] == '?')) + { + str_ind++; + pattern_ind++; + } + else if (pattern_ind < patt_len && pattern[pattern_ind] == '*') + { + star = pattern_ind++; + m = str_ind; + } + else if (star != -1) + { + pattern_ind = star + 1; + str_ind = ++m; + } + else + { + ok = false; + break; + } + } + if(ok) + { + while (pattern_ind < patt_len && pattern[pattern_ind] == '*') + pattern_ind++; + ok = pattern_ind == patt_len; + } + + return ok; + } const char* to_lower(std::string& str) { std::transform(str.begin(), str.end(), str.begin(), tolower); diff --git a/sdk/hginclude/utils.h b/sdk/hginclude/utils.h index bd0bda5..d1d3abf 100644 --- a/sdk/hginclude/utils.h +++ b/sdk/hginclude/utils.h @@ -33,11 +33,13 @@ namespace utils std::string temporary_path(void); std::string format_current_time(void); std::string get_module_full_path(const char* part_name = nullptr/*nullptr to get main-pe/first module's full path*/); + std::string find_file(const char* root_dir, const char* part_name, bool recursive = false); std::string target_file_from_link(const char* lnk_file); std::string get_ini_value(const char* seg, const char* key, const char* cfg_file); // return "" if not found std::string load_mini_file(const char* file, int* err); // <= 1MB int save_2_file(void* data, size_t len, const char* file, bool append = false/*append or new*/, size_t max_size = -1/*in append mode, truncate file if size is exceeded this value if was not -1*/); + bool is_match_pattern(const char* text, const char* pattern); const char* to_lower(std::string& str); // return str.c_str() const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str() diff --git a/twain/ds/huagaods.cpp b/twain/ds/huagaods.cpp index bc756cd..171b219 100644 --- a/twain/ds/huagaods.cpp +++ b/twain/ds/huagaods.cpp @@ -1127,8 +1127,12 @@ Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui) bUiOnly_ = false; show_setting_ = false; scanner_->twain_set_transfer((twain_xfer)m_capXferMech); - if (!ui.showUi()) + if (!ui.showUi() || !scanner_->ui_is_ok()) { + if(ui.showUi()) + { + utils::to_log(LOG_LEVEL_WARNING, "APP want to show setting UI, but UI is not in service!\n"); + } scanner_->ui_show_progress((HWND)ui.parent().raw(), m_bIndicator); //if (m_bIndicator && !) // return seqError(); diff --git a/twain/ds/sane_helper.cpp b/twain/ds/sane_helper.cpp index 2140435..e805fed 100644 --- a/twain/ds/sane_helper.cpp +++ b/twain/ds/sane_helper.cpp @@ -86,7 +86,7 @@ sane_helper::sane_helper() std::string path(win_util::get_registry_string(HKEY_LOCAL_MACHINE, (std::string("Software\\") + PRODUCT_VENDOR + "Scan").c_str(), sizeof(void*) == 4 ? "DriverPath" : "DriverPath64")); dll_root_ = path + PATH_SEPARATOR; #else - std::string path(utils::get_module_full_path("libc.so")); + std::string path(utils::get_module_full_path("libc*.so*")); size_t pos = path.rfind(PATH_SEPARATOR[0]); if(pos++ != std::string::npos) diff --git a/twain/ds/scanner.cpp b/twain/ds/scanner.cpp index 53ee9b2..bd54fc5 100644 --- a/twain/ds/scanner.cpp +++ b/twain/ds/scanner.cpp @@ -259,25 +259,23 @@ namespace callback static void init_ui(void) { -#if OS_WIN - std::string root(utils::get_module_full_path("scanner")); -#else - std::string root(utils::get_module_full_path("driver")); -#endif + std::string root(utils::get_module_full_path(SCANNER_DRIVER_PART_NAME)); size_t pos = root.rfind(PATH_SEPARATOR[0]); - if(pos++ != std::string::npos) + if(pos != std::string::npos) root.erase(pos); -#if defined(WIN32) || defined(_WIN64) - root += OEM_SHORT_NAME_E; -#else - std::string vnd(OEM_SHORT_NAME_E); - - std::transform(vnd.begin(), vnd.end(), vnd.begin(), toupper); - root += "lib" + vnd; -#endif - root += "TwainUI."; - root += DLL_EXTESION; + root = utils::find_file(root.c_str(), "*twainui*", false); + utils::to_log(LOG_LEVEL_DEBUG, "TwainUI component: %s\n", root.c_str()); +// #if defined(WIN32) || defined(_WIN64) +// root += OEM_SHORT_NAME_E; +// #else +// std::string vnd(OEM_SHORT_NAME_E); +// +// std::transform(vnd.begin(), vnd.end(), vnd.begin(), toupper); +// root += "lib" + vnd; +// #endif +// root += "TwainUI."; +// root += DLL_EXTESION; hui = LoadLibraryExA(root.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); if (!hui) { @@ -3023,7 +3021,7 @@ COM_API_IMPLEMENT(scanner, void, ui_hide(void)) } COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void)) { - return true; + return callback::show_setting_ui != nullptr; }