优化属性重载

This commit is contained in:
gb 2023-11-04 11:44:30 +08:00
parent d14e2327ad
commit 7bb5390417
4 changed files with 63 additions and 25 deletions

View File

@ -231,7 +231,7 @@ hg_sane_middleware::hg_sane_middleware(void) : init_ok_(false), offline_(nullptr
{
offline_ = new DEVINST;
offline_->opts = new sane_options();
reload_options(offline_);
reload_options(offline_, RELOAD_FOR_DEVICE_OPEN);
}
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait for device OK
@ -390,7 +390,7 @@ hg_sane_middleware::LPDEVINST hg_sane_middleware::find_openning_device(const cha
return ret;
}
bool hg_sane_middleware::reload_options(LPDEVINST inst)
bool hg_sane_middleware::reload_options(LPDEVINST inst, int reason)
{
long len = 0;
char *buf = nullptr;
@ -404,7 +404,7 @@ bool hg_sane_middleware::reload_options(LPDEVINST inst)
if (err == SCANNER_ERR_OK && len)
{
if (!inst->opts->init_from(buf, local_utility::dump_msg))
if (!inst->opts->init_from(buf, local_utility::dump_msg, reason == RELOAD_FOR_DEVICE_OPEN))
err = SCANNER_ERR_DATA_DAMAGED;
}
if (buf)
@ -485,7 +485,7 @@ scanner_err hg_sane_middleware::write_value(scanner_handle h, const char* name,
if (err == SCANNER_ERR_RELOAD_OPT_PARAM || err == SCANNER_ERR_CONFIGURATION_CHANGED)
{
if(optinst)
reload_options(optinst);
reload_options(optinst, RELOAD_FOR_OPT_CHANGED);
if (affect)
*affect = SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
err = SCANNER_ERR_OK;
@ -668,7 +668,7 @@ SANE_Status hg_sane_middleware::open_device(SANE_String_Const devicename, SANE_H
inst->dev = h;
inst->name = devicename;
inst->opts = new sane_options();
if(reload_options(inst))
if(reload_options(inst, RELOAD_FOR_DEVICE_OPEN))
{
openning_.push_back(inst);
*handle = hg_sane_middleware::scanner_handle_to_sane(h);
@ -850,7 +850,7 @@ SANE_Status hg_sane_middleware::ex_io_control(SANE_Handle h, unsigned long code,
{
int nc = code;
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "the setting '0x%08x' affects other options value, RELOAD ...\n", nc);
reload_options(dev);
reload_options(dev, RELOAD_FOR_OPT_CHANGED);
}
return local_utility::scanner_err_2_sane_statu(ret);

View File

@ -48,7 +48,12 @@ class hg_sane_middleware
LPDEVINST find_openning_device(SANE_Handle h, bool rmv = false);
LPDEVINST find_openning_device(const char* name, bool rmv = false);
bool reload_options(LPDEVINST inst);
enum
{
RELOAD_FOR_DEVICE_OPEN = 0,
RELOAD_FOR_OPT_CHANGED,
};
bool reload_options(LPDEVINST inst, int reason);
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);

View File

@ -248,17 +248,30 @@ bool sane_opt::from_json_text(const char* key, const char* json, void(*err_msg)(
bool ret = false;
std::string text(json);
gb_json *jsn = new gb_json();
char *buf = nullptr;
if (jsn->attach_text(&text[0]))
{
jsn->key() = key;
ret = from_json_object(jsn, err_msg);
}
jsn->release();
return ret;
}
bool sane_opt::from_json_object(gb_json* jsn, void(*err_msg)(const char*))
{
bool ret = false;
std::string text("");
clear();
while (jsn->attach_text(&text[0]))
while (1)
{
if (!jsn->get_value("fix-id", fix_id_))
fix_id_ = -1;
if(!jsn->get_value("enabled", enabled_))
if (!jsn->get_value("enabled", enabled_))
enabled_ = true;
set_opt_desc_string_value((char**)&opt_desc_.name, key);
set_opt_desc_string_value((char**)&opt_desc_.name, jsn->key().c_str());
if (jsn->get_value("title", text))
{
set_opt_desc_string_value((char**)&opt_desc_.title, text.c_str());
@ -323,7 +336,6 @@ bool sane_opt::from_json_text(const char* key, const char* json, void(*err_msg)(
ret = true;
break;
}
jsn->release();
return ret;
}
@ -369,14 +381,15 @@ void sane_options::clear(void)
opt_cnt_ = 0;
}
bool sane_options::init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*))
bool sane_options::init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*), bool clear_prev)
{
bool ret = false;
gb_json* jsn = new gb_json();
std::string str(jsn_text);
int sn = 0;
// clear(); // keep the SANE_Option_Descriptor*
if(clear_prev)
clear(); // keep the SANE_Option_Descriptor*
if (jsn->attach_text(&str[0]))
{
gb_json* child = jsn->first_child();
@ -386,14 +399,15 @@ bool sane_options::init_from(const char* jsn_text/*all options*/, void(*err_msg)
{
str = std::move(child->to_string());
sn++;
ret = add_or_replace_opt(sn, child->key().c_str(), str.c_str(), err_msg);
ret = add_or_replace_opt(sn, child, err_msg);
child->release();
if (!ret)
{
child->release();
if (clear_prev)
clear();
break;
}
child->release();
child = jsn->next_child();
}
}
@ -403,17 +417,33 @@ bool sane_options::init_from(const char* jsn_text/*all options*/, void(*err_msg)
}
bool sane_options::add_or_replace_opt(int& sn, const char* name, const char* jsn_text, void(*err_msg)(const char*))
{
if (opts_.count(sn))
bool ret = false;
std::string text(jsn_text);
gb_json *jsn = new gb_json();
if (jsn->attach_text(&text[0]))
{
bool en = opts_[sn]->is_enabled(),
ret = opts_[sn]->from_json_text(name, jsn_text, err_msg);
jsn->key() = name;
ret = add_or_replace_opt(sn, jsn, err_msg);
}
jsn->release();
return ret;
}
bool sane_options::add_or_replace_opt(int& sn, gb_json* jsn, void(*err_msg)(const char*))
{
int id = sn;
if (!jsn->get_value("fix-id", id))
id = sn;
if (opts_.count(id))
{
return opts_[id]->from_json_object(jsn, err_msg);
}
sane_opt* opt = new sane_opt();
if (opt->from_json_text(name, jsn_text, err_msg))
if (opt->from_json_object(jsn, err_msg))
{
if (opt->is_visible())
{

View File

@ -45,6 +45,7 @@ public:
bool is_visible(void);
bool from_json_text(const char* key, const char* json, void(*err_msg)(const char*) = nullptr);
bool from_json_object(gb_json* jsn, void(*err_msg)(const char*) = nullptr);
};
@ -57,13 +58,15 @@ class sane_options
void clear(void);
bool add_or_replace_opt(int& sn, const char* name, const char* jsn_text, void(*err_msg)(const char*));
bool add_or_replace_opt(int& sn, gb_json* jsn, void(*err_msg)(const char*));
public:
sane_options();
~sane_options();
public:
bool init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*));
// clear_prev: call from device openned or closed, should clear all options; call from SANE_RELOAD_xxx should keep the SANE_Option_Descriptor* stable
bool init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*), bool clear_prev);
SANE_Option_Descriptor* get_opt_descriptor(const void* opt, int* fix_id = nullptr, int ind_base = 0);
int get_option_count(void);
bool enum_invisible_fix_ids(struct _fix_id_cb* fcb); // return whether the callback stopped the enumeration