diff --git a/hgdriver/hgdev/scanner_manager.cpp b/hgdriver/hgdev/scanner_manager.cpp index 9fd28ae..c34e9a8 100644 --- a/hgdriver/hgdev/scanner_manager.cpp +++ b/hgdriver/hgdev/scanner_manager.cpp @@ -939,6 +939,7 @@ scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const cha { sane_opt_provider* sop = dynamic_cast(SCAN_PTR(h)); err = (scanner_err)dev_opts_->restore(sop); + utils::to_log(LOG_LEVEL_DEBUG, "Restore all options ...\n"); } else { diff --git a/hgdriver/hgdev/user-opt/device_opt.cpp b/hgdriver/hgdev/user-opt/device_opt.cpp index 9b3f462..f560423 100644 --- a/hgdriver/hgdev/user-opt/device_opt.cpp +++ b/hgdriver/hgdev/user-opt/device_opt.cpp @@ -140,32 +140,6 @@ static std::string get_real_value(gb_json* jsn, const char* type) return ""; } -static bool pick_bracket(const char* exp, const char** end) -{ - bool ret = false; - int balance = 1; - - exp = strstr(exp, "["); - if (exp++) - { - while (*exp && balance) - { - if (*exp == '[') - balance++; - else if (*exp == ']') - balance--; - exp++; - } - if (balance == 0) - { - *end = exp - 1; - ret = true; - } - } - - return ret; -} - static struct { std::string name; @@ -765,13 +739,14 @@ bool device_option::parse_simple_logic_expression(gb_json* root, const char* exp // substr function ... if (strstr(tag, "left[") || strstr(tag, "right[") || strstr(tag, "mid[")) { - const char* end = nullptr; - bool ret = pick_bracket(tag, &end); + const char* end = nullptr, *start = strstr(tag, "["); + int l = string_util::find_end_of_pair(start + 1, '[', ']'); + bool ret = start[++l] == ']'; if (ret) { - std::string exp(calc.name + (end + 1)), - name1(tag, end - tag + 1); + std::string exp(calc.name + (start + l + 1)), + name1(tag, start + l - tag + 1); name1.insert(0, calc.name + "."); ret = device_option::parse_simple_logic_expression(root, exp.c_str(), name, calc); if (ret) diff --git a/hgdriver/hgdev/user-opt/device_opt.h b/hgdriver/hgdev/user-opt/device_opt.h index 1e4848c..f2050b6 100644 --- a/hgdriver/hgdev/user-opt/device_opt.h +++ b/hgdriver/hgdev/user-opt/device_opt.h @@ -342,6 +342,7 @@ protected: } } + public: device_option(std::function user_priv = std::function() , std::function log = std::function()); diff --git a/hgdriver/hgdev/user-opt/simple_logic.cpp b/hgdriver/hgdev/user-opt/simple_logic.cpp index 61df9e6..86cf7ec 100644 --- a/hgdriver/hgdev/user-opt/simple_logic.cpp +++ b/hgdriver/hgdev/user-opt/simple_logic.cpp @@ -52,7 +52,7 @@ namespace string_util return end; } - void skip_space(const char*& ptr, const char* space = " \t") + void skip_space(const char*& ptr, const char* space) { char mark[2] = { 0 }; @@ -65,13 +65,7 @@ namespace string_util } } - enum - { - TRIM_LEFT = 1, - TRIM_RIGHT, - TRIM_BOTH, - }; - void trim(std::string& str, int type = TRIM_BOTH) + void trim(std::string& str, int type) { int pos = 0; @@ -181,43 +175,53 @@ bool simple_logic::parse_internal(const char* expr, int* end, void(*leaf)(const } std::string sub(ptr + 1, len - 1); - simple_logic *e = new simple_logic(); - int over = 0; - bool not_v = false; - - if (first) + if (sub.find("||") == std::string::npos || + sub.find("&&") == std::string::npos || + sub.find("^") == std::string::npos) { - while (first < ptr) + // count as function ... + ptr += len; + } + else + { + simple_logic* e = new simple_logic(); + int over = 0; + bool not_v = false; + + if (first) { - if (*first == '!') - not_v ^= true; - else + while (first < ptr) + { + if (*first == '!') + not_v ^= true; + else + break; + first++; + } + if (first < ptr) + { + *end = first - expr; + good = false; + delete e; break; - first++; + } + first = nullptr; } - if (first < ptr) + + if (e->parse(sub.c_str(), &over, leaf, leaf_param)) { - *end = first - expr; + e->set_not(not_v); + ele.push_back(e); + ptr += len; + need_oper = true; + } + else + { + *end = ptr - expr + 1 + over; good = false; delete e; break; } - first = nullptr; - } - - if (e->parse(sub.c_str(), &over, leaf, leaf_param)) - { - e->set_not(not_v); - ele.push_back(e); - ptr += len; - need_oper = true; - } - else - { - *end = ptr - expr + 1 + over; - good = false; - delete e; - break; } } else if (*ptr == '|') diff --git a/hgdriver/hgdev/user-opt/simple_logic.h b/hgdriver/hgdev/user-opt/simple_logic.h index 26cebbf..9868a7c 100644 --- a/hgdriver/hgdev/user-opt/simple_logic.h +++ b/hgdriver/hgdev/user-opt/simple_logic.h @@ -16,6 +16,29 @@ #include #include +namespace string_util +{ + // Function: find the ending position in str + // + // Parameter: str - the string beginning after the first letter 'head' + // + // head - the leading letter, can be emblaced + // + // tail - the ending letter + // + // Return: position at the ending letter, or '\0' in the string + int find_end_of_pair(const char* str, char head, char tail); + void skip_space(const char*& ptr, const char* space = " \t"); + + enum + { + TRIM_LEFT = 1, + TRIM_RIGHT, + TRIM_BOTH, + }; + void trim(std::string& str, int type = TRIM_BOTH); +}; + class simple_logic { int oper_; diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp index 8d2738f..2099eed 100644 --- a/hgsane/sane_hg_mdw.cpp +++ b/hgsane/sane_hg_mdw.cpp @@ -24,6 +24,7 @@ #include #include "../sdk/hginclude/utils.h" #include +#include "../hgdriver/hgdev/user-opt/device_opt.h" // for readable_text(SANE_Value_Type type, void* value) #ifndef SIGUSR1 #define SIGUSR1 10 @@ -527,7 +528,7 @@ SANE_Status hg_sane_middleware::get_current_value(LPDEVINST inst, const void* op return SANE_STATUS_INVAL; } } -SANE_Status hg_sane_middleware::set_value(LPDEVINST inst, const void* opt, void* value, SANE_Int* affect, bool to_default) +SANE_Status hg_sane_middleware::set_value(LPDEVINST inst, const void* opt, void* value, SANE_Int* affect, bool to_default, std::string* title, std::string* val_text_before, std::string* val_text_after) { bool empty_value = false; SANE_Option_Descriptor* desc = inst->opts->get_opt_descriptor(opt); @@ -545,12 +546,21 @@ SANE_Status hg_sane_middleware::set_value(LPDEVINST inst, const void* opt, void* return SANE_STATUS_INVAL; } + SANE_Value_Type type = desc->type; + + if (val_text_before && value) + *val_text_before = sane_opt::readable_text(desc->type, value); + if (title) + *title = desc->title; + if (IS_CAP_READONLY(desc->cap)) - return SANE_STATUS_UNSUPPORTED; + return SANE_STATUS_ACCESS_DENIED; if (to_default && (desc->cap & SANE_CAP_AUTOMATIC) == 0) return SANE_STATUS_UNSUPPORTED; scanner_err err = write_value(inst->dev, desc->name, desc->type, value, to_default, inst, affect); + if (val_text_after && value) + *val_text_after = sane_opt::readable_text(type, value); return local_utility::scanner_err_2_sane_statu(err); } @@ -784,7 +794,25 @@ SANE_Status hg_sane_middleware::control_option(SANE_Handle h, const void* option } else if (action == SANE_ACTION_SET_VALUE || action == SANE_ACTION_SET_AUTO) { - err = set_value(inst, option, value, after_do, action == SANE_ACTION_SET_AUTO); + std::string title(""), before(""), after(""); + + err = set_value(inst, option, value, after_do, action == SANE_ACTION_SET_AUTO, &title, &before, &after); + + if (action == SANE_ACTION_SET_AUTO) + { + if(after.empty()) + utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "Restore '%s' = %s\n" + , title.c_str(), hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err))); + else + utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "Restore '%s' to '%s' = %s\n" + , title.c_str(), after.c_str(), hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err))); + } + else if(before != after) + utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "set '%s' to '%s'(APPLIED: %s) = %s\n" + , title.c_str(), before.c_str(), after.c_str(), hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err))); + else + utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "set '%s' to '%s' = %s\n" + , title.c_str(), before.c_str(), hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err))); } // extension ... diff --git a/hgsane/sane_hg_mdw.h b/hgsane/sane_hg_mdw.h index e1e5215..63a51d3 100644 --- a/hgsane/sane_hg_mdw.h +++ b/hgsane/sane_hg_mdw.h @@ -53,7 +53,7 @@ class hg_sane_middleware scanner_err read_value(scanner_handle h, const char* name, SANE_Value_Type type, size_t len, void* value, bool to_default); scanner_err write_value(scanner_handle h, const char* name, SANE_Value_Type type, void* value, bool to_default, LPDEVINST optinst, SANE_Int* affect); SANE_Status get_current_value(LPDEVINST inst, const void* opt, void* value, bool default_val); - SANE_Status set_value(LPDEVINST inst, const void* opt, void* value, SANE_Int* affect, bool to_default); + SANE_Status set_value(LPDEVINST inst, const void* opt, void* value, SANE_Int* affect, bool to_default, std::string* title = nullptr, std::string* val_text_before = nullptr, std::string* val_text_after = nullptr); SANE_Status get_option_fixed_id(LPDEVINST inst, const void* opt, void* value); protected: diff --git a/hgsane/sane_opt/sane_opts.cpp b/hgsane/sane_opt/sane_opts.cpp index ade71af..7f99252 100644 --- a/hgsane/sane_opt/sane_opts.cpp +++ b/hgsane/sane_opt/sane_opts.cpp @@ -16,6 +16,33 @@ sane_opt::~sane_opt() clear(); } +std::string sane_opt::readable_text(const char* type, void* value) +{ + if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0) + return sane_opt::readable_text(SANE_TYPE_BOOL, value); + else if (strcmp(type, JSON_SANE_TYPE_INT) == 0) + return sane_opt::readable_text(SANE_TYPE_INT, value); + else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0) + return sane_opt::readable_text(SANE_TYPE_FIXED, value); + else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0) + return sane_opt::readable_text(SANE_TYPE_STRING, value); + else + return ""; +} +std::string sane_opt::readable_text(SANE_Value_Type type, void* value) +{ + if (type == SANE_TYPE_BOOL) + return *(bool*)value ? "true" : "false"; + else if (type == SANE_TYPE_INT) + return std::to_string(*(int*)value); + else if (type == SANE_TYPE_FIXED) + return std::to_string(*(double*)value); + else if (type == SANE_TYPE_STRING) + return (char*)value; + else + return ""; +} + void sane_opt::clear() { if (opt_desc_.desc) diff --git a/hgsane/sane_opt/sane_opts.h b/hgsane/sane_opt/sane_opts.h index 487bbbf..09b4aee 100644 --- a/hgsane/sane_opt/sane_opts.h +++ b/hgsane/sane_opt/sane_opts.h @@ -34,6 +34,9 @@ public: sane_opt(); ~sane_opt(); + static std::string readable_text(const char* type, void* value); + static std::string readable_text(SANE_Value_Type type, void* value); + public: int get_fix_id(void); SANE_Option_Descriptor* get_descriptor(void); diff --git a/sdk/json/gb_json.cpp b/sdk/json/gb_json.cpp index 07146ea..7b47f92 100644 --- a/sdk/json/gb_json.cpp +++ b/sdk/json/gb_json.cpp @@ -235,9 +235,9 @@ bool gb_json::attach_text(char* json_txt) cJSON* jsn = cJSON_Parse(json_txt); if (jsn) { - char *text = cJSON_Print(jsn); - if (text) - free(text); + //char *text = cJSON_Print(jsn); + //if (text) + // free(text); from_cjson(jsn->child); cJSON_Delete(jsn);