code_device/hgdriver/hgdev/device_opt.cpp

1266 lines
26 KiB
C++
Raw Normal View History

#include "device_opt.h"
#include <hginclude/utils.h>
#include <huagao/hgscanner_error.h>
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include <lang/app_language.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// image-processing jsons ...
#define JSON_SANE_TYPE_BOOL "bool"
#define JSON_SANE_TYPE_INT "int"
#define JSON_SANE_TYPE_FIXED "float"
#define JSON_SANE_TYPE_STRING "string"
template<class T, class TC>
static void copy_simple_type(TC* dst, T& src)
{
*dst = src;
}
template<class T, class TC>
static bool refine_data_to_range(gb_json* jsn, void* value, void(*cp)(TC*, T&))
{
bool refined = false;
gb_json* range = nullptr;
jsn->get_value("range", range);
if (range)
{
2023-09-09 10:09:20 +00:00
T vl, vu, s;
if (range->get_value("min", vl))
{
if (*(TC*)value < vl)
{
cp((TC*)value, vl);
refined = true;
}
else if (range->get_value("max", vu))
{
if (*(TC*)value > vu)
{
cp((TC*)value, vu);
refined = true;
}
else if (range->get_value("step", s))
{
T cur(*(TC*)value);
vl = cur - vl;
vl /= s;
if (!IS_DOUBLE_EQUAL(vl, (int)vl))
{
vl += .5f;
vl = (int)vl * s;
if (vl > vu)
vl = vu;
cp((TC*)value, vl);
refined = true;
}
}
}
}
else
{
gb_json* val = range->first_child();
bool found = false;
while (val)
{
if (val->value(vl))
{
if (*(TC*)value == vl)
{
found = true;
val->release();
break;
}
}
val->release();
val = range->next_child();
}
if (!found)
{
if (jsn->get_value("default", vl))
{
refined = true;
cp((TC*)value, vl);
}
}
}
range->release();
}
return refined;
}
static bool refine_string_data(gb_json* jsn, void* value)
{
bool refined = false;
gb_json* range = nullptr;
std::string v((char*)value);
jsn->get_value("range", range);
if (range)
{
std::string vl(""), vu(""), s("");
if (range->get_value("min", vl))
{
2023-09-09 10:09:20 +00:00
if (v < vl)
{
2023-09-09 10:09:20 +00:00
strcpy((char*)value, vl.c_str());
refined = true;
}
2023-09-09 10:09:20 +00:00
else if (range->get_value("max", vu))
{
2023-09-09 10:09:20 +00:00
if (v > vu)
{
2023-09-09 10:09:20 +00:00
strcpy((char*)value, vu.c_str());
refined = true;
}
2023-09-09 10:09:20 +00:00
//else if (range->get_value("step", s))
//{
// T cur(*(TC*)value);
//
// vl = cur - vl;
// vl /= s;
// if (!IS_DOUBLE_EQUAL(vl, (int)vl))
// {
// vl += .5f;
// vl = (int)vl * s;
// if (vl > vu)
// vl = vu;
// cp((TC*)value, vl);
// refined = true;
// }
//}
}
}
else
{
gb_json* val = range->first_child();
bool found = false;
while (val)
{
2023-09-09 10:09:20 +00:00
if (val->value(vl))
{
2023-09-09 10:09:20 +00:00
if (v == vl)
{
found = true;
val->release();
break;
}
}
val->release();
val = range->next_child();
}
if (!found)
{
2023-09-09 10:09:20 +00:00
if (jsn->get_value("default", vl))
{
refined = true;
2023-09-09 10:09:20 +00:00
strcpy((char*)value, vl.c_str());
}
}
}
range->release();
}
return refined;
}
template<class T>
static std::string get_real_value(gb_json* jsn, bool def_val)
{
T v;
jsn->get_value(def_val ? "default" : "cur", v);
return std::move(std::string((char*)&v, sizeof(v)));
}
template<class T>
static std::string get_real_string(gb_json* jsn, bool def_val)
{
T v;
jsn->get_value(def_val ? "default" : "cur", v);
return std::move(v);
}
static std::string get_real_value(gb_json* jsn, const char* type)
{
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
bool v = false;
jsn->value(v);
return std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
int v = 0;
jsn->value(v);
return std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
double v = .0f;
jsn->value(v);
return std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
std::string v("");
jsn->value(v);
return std::move(v);
}
return "";
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// class device_opt ...
bool device_option::condition_value::set_value(gb_json* jsn, const char* type, device_option* parent) // jsn contains only ONE value or its object
{
bool ret = false;
clear();
if (jsn->is_leaf_node())
{
CONDVAL cv;
cv.logic = nullptr;
cv.value = get_real_value(jsn, type);
vals_.push_back(cv);
ret = true;
}
else
{
gb_json* item = jsn->first_child();
CONDVAL val0; // make the default value at last
ret = true;
val0.logic = nullptr;
val0.value = "";
while (item)
{
// "condition": value
std::string cond(item->key()), val("");
CONDVAL cv;
if (cond == "default")
{
val0.logic = nullptr;
val0.value = get_real_value(item, type);
}
else
{
int end = 0;
cv.logic = new simple_logic();
if (cv.logic->parse(cond.c_str(), &end, &device_option::init_condition, parent))
{
cv.value = get_real_value(item, type);
vals_.push_back(cv);
}
else
{
delete cv.logic;
item->release();
ret = false;
break;
}
}
item->release();
item = jsn->next_child();
}
if (!val0.value.empty())
vals_.push_back(val0);
}
return ret;
}
bool device_option::range_value::set_value(gb_json* jsn, const char* type, device_option* parent) // jsn contains all range object
{
bool ret = true;
clear();
if (jsn->is_array())
{
gb_json* item = jsn->first_child();
while (item)
{
device_option::condition_value* v = new device_option::condition_value();
if (v->set_value(item, type, parent))
{
vals_.push_back(v);
}
else
{
delete v;
item->release();
ret = false;
break;
}
item->release();
item = jsn->next_child();
}
}
else
{
condition_value* cv = nullptr;
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
cv = device_option::to_condition_value<bool>(jsn, "min", type, parent);
ret = false;
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<bool>(jsn, "max", type, parent);
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<bool>(jsn, "step", type, parent);
if (cv)
{
vals_.push_back(cv);
ret = true;
}
}
}
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
cv = device_option::to_condition_value<int>(jsn, "min", type, parent);
ret = false;
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<int>(jsn, "max", type, parent);
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<int>(jsn, "step", type, parent);
if (cv)
{
vals_.push_back(cv);
ret = true;
}
}
}
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
cv = device_option::to_condition_value<double>(jsn, "min", type, parent);
ret = false;
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<double>(jsn, "max", type, parent);
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<double>(jsn, "step", type, parent);
if (cv)
{
vals_.push_back(cv);
ret = true;
}
}
}
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
cv = device_option::to_condition_value<std::string>(jsn, "min", type, parent);
ret = false;
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<std::string>(jsn, "max", type, parent);
if (cv)
{
vals_.push_back(cv);
cv = device_option::to_condition_value<std::string>(jsn, "step", type, parent);
if (cv)
{
vals_.push_back(cv);
ret = true;
}
}
}
}
}
return ret;
}
device_option::device_option() : origin_(nullptr), now_(nullptr)
{}
device_option::~device_option()
{
clear();
}
bool device_option::is_equal_b(gb_json* opt, void* val, void* v1, void* v2)
{
return *(bool*)val == *(bool*)v1;
}
bool device_option::is_equal_i(gb_json* opt, void* val, void* v1, void* v2)
{
return *(int*)val == *(int*)v1;
}
bool device_option::is_equal_f(gb_json* opt, void* val, void* v1, void* v2)
{
return IS_DOUBLE_EQUAL(*(double*)val, *(double*)v1);
}
bool device_option::is_equal_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) == 0;
}
bool device_option::is_less_b(gb_json* opt, void* val, void* v1, void* v2)
{
return *(bool*)val < *(bool*)v1;
}
bool device_option::is_less_i(gb_json* opt, void* val, void* v1, void* v2)
{
return *(int*)val < *(int*)v1;
}
bool device_option::is_less_f(gb_json* opt, void* val, void* v1, void* v2)
{
return *(double*)val < *(double*)v1;
}
bool device_option::is_less_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) < 0;
}
bool device_option::is_great_b(gb_json* opt, void* val, void* v1, void* v2)
{
return *(bool*)val > *(bool*)v1;
}
bool device_option::is_great_i(gb_json* opt, void* val, void* v1, void* v2)
{
return *(int*)val > *(int*)v1;
}
bool device_option::is_great_f(gb_json* opt, void* val, void* v1, void* v2)
{
return *(double*)val > *(double*)v1;
}
bool device_option::is_great_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) > 0;
}
bool device_option::is_between_b(gb_json* opt, void* val, void* v1, void* v2)
{
return *(bool*)val == *(bool*)v1 || *(bool*)val <= *(bool*)v2;
}
bool device_option::is_between_i(gb_json* opt, void* val, void* v1, void* v2)
{
return *(int*)val >= *(int*)v1 && *(int*)val <= *(int*)v2;
}
bool device_option::is_between_f(gb_json* opt, void* val, void* v1, void* v2)
{
return *(double*)val >= *(double*)v1 && *(double*)val <= *(double*)v2;
}
bool device_option::is_between_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) >= 0 &&
strcmp((char*)val, from_default_language((char*)v2)) <= 0;
}
bool device_option::is_opt_enabled(gb_json* opt, void* val, void* v1, void* v2)
{
bool en = true;
if (!opt->get_value("enabled", en))
en = true;
return en;
}
bool device_option::get_equal(const char* type, bool(**f)(gb_json*, void*, void*, void*))
{
bool ret = true;
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
*f = &device_option::is_equal_b;
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
*f = &device_option::is_equal_i;
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
*f = &device_option::is_equal_f;
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
*f = &device_option::is_equal_s;
}
else
{
ret = false;
}
return ret;
}
bool device_option::get_less(const char* type, bool(**f)(gb_json*, void*, void*, void*))
{
bool ret = true;
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
*f = &device_option::is_less_b;
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
*f = &device_option::is_less_i;
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
*f = &device_option::is_less_f;
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
*f = &device_option::is_less_s;
}
else
{
ret = false;
}
return ret;
}
bool device_option::get_great(const char* type, bool(**f)(gb_json*, void*, void*, void*))
{
bool ret = true;
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
*f = &device_option::is_great_b;
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
*f = &device_option::is_great_i;
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
*f = &device_option::is_great_f;
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
*f = &device_option::is_great_s;
}
else
{
ret = false;
}
return ret;
}
bool device_option::get_between(const char* type, bool(**f)(gb_json*, void*, void*, void*))
{
bool ret = true;
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
*f = &device_option::is_between_b;
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
*f = &device_option::is_between_i;
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
*f = &device_option::is_between_f;
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
*f = &device_option::is_between_s;
}
else
{
ret = false;
}
return ret;
}
std::string device_option::from_text_value(const char* type, const char* text_val)
{
std::string real_v("");
if (strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
bool v = STRICMP(text_val, "true") == 0;
real_v = std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
int v = atoi(text_val);
real_v = std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
double v = atof(text_val);
real_v = std::string((char*)&v, sizeof(v));
}
else if (strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
real_v = text_val;
}
return std::move(real_v);
}
bool device_option::parse_simple_logic_expression(gb_json* root, const char* expr, std::string* name, EXPRCALC& calc)
{
const char* opers[] = { ">", "<", "!", "=", "." }, * tag = nullptr;
for (auto& v : opers)
{
tag = strstr(expr, v);
2023-09-09 10:09:20 +00:00
if (tag)
break;
}
if (!tag)
return false;
std::string n(expr, tag - expr);
bool ret = true;
gb_json *child = nullptr;
if (name)
*name = n;
calc.name = n;
root->get_value(n.c_str(), child);
if (!child)
return false;
if (!child->get_value("type", n))
{
child->release();
return false;
}
child->release();
if (*tag == '>')
{
if (tag[1] == '=')
{
if (!device_option::get_less(n.c_str(), &calc.compare))
return false;
calc.not_op = true;
tag++;
}
else
{
if (!device_option::get_great(n.c_str(), &calc.compare))
return false;
calc.not_op = false;
}
tag++;
}
else if (*tag == '<')
{
if (tag[1] == '=')
{
if (!device_option::get_great(n.c_str(), &calc.compare))
return false;
calc.not_op = true;
tag++;
}
else
{
if (!device_option::get_less(n.c_str(), &calc.compare))
return false;
calc.not_op = false;
}
tag++;
}
else if (*tag == '!')
{
if (tag[1] == '=')
{
if (!device_option::get_equal(n.c_str(), &calc.compare))
return false;
calc.not_op = true;
tag++;
}
else
{
return false;
}
tag++;
}
else if (*tag == '=')
{
if (tag[1] == '=')
{
if (!device_option::get_equal(n.c_str(), &calc.compare))
return false;
calc.not_op = false;
tag++;
}
else
{
return false;
}
tag++;
}
else if (*tag++ == '.')
{
calc.compare = &device_option::is_opt_enabled;
if (strcmp(tag, "enabled") == 0)
{
calc.not_op = false;
}
else if (strcmp(tag, "!enabled") == 0)
{
calc.not_op = true;
}
else
{
return false;
}
tag = "";
}
else
{
return false;
}
// value ...
if (*tag)
{
if (*tag == '[')
{
const char* next = strstr(tag++, ",");
if (next++ == nullptr)
{
ret = false;
}
else
{
std::string v(tag, next - tag - 1);
calc.val1 = device_option::from_text_value(n.c_str(), v.c_str());
tag = strstr(next, "]");
if (!tag)
ret = false;
else
{
v = std::string(next, tag - next);
calc.val2 = device_option::from_text_value(n.c_str(), v.c_str());
}
}
}
else
{
calc.val1 = device_option::from_text_value(n.c_str(), tag);
}
}
return ret;
}
void device_option::init_condition(const char* expr, void* param)
{
if (((device_option*)param)->compare_.count(expr))
return;
std::string name("");
EXPRCALC calc;
if (device_option::parse_simple_logic_expression(((device_option*)param)->origin_, expr, &name, calc))
{
((device_option*)param)->compare_[expr] = calc;
if (std::find(((device_option*)param)->master_opts_.begin(), ((device_option*)param)->master_opts_.end(), name)
== ((device_option*)param)->master_opts_.end())
((device_option*)param)->master_opts_.push_back(name);
}
}
bool device_option::calc_simple_logic_expression(const char* expr, void* param)
{
device_option* obj = (device_option*)param;
bool ret = true;
if (obj->compare_.count(expr))
{
gb_json* child = nullptr;
2023-09-09 10:09:20 +00:00
if(obj->now_)
obj->now_->get_value(obj->compare_[expr].name.c_str(), child);
else
obj->origin_->get_value(obj->compare_[expr].name.c_str(), child);
if (child)
{
bool bv = false;
int nv = 0;
double dv = .0f;
std::string sv("");
void* val = nullptr;
child->get_value("type", sv);
if (strcmp(sv.c_str(), JSON_SANE_TYPE_BOOL) == 0)
{
sv = get_real_value<bool>(child, false);
}
else if (strcmp(sv.c_str(), JSON_SANE_TYPE_INT) == 0)
{
sv = get_real_value<int>(child, false);
}
else if (strcmp(sv.c_str(), JSON_SANE_TYPE_FIXED) == 0)
{
sv = get_real_value<double>(child, false);
}
else if (strcmp(sv.c_str(), JSON_SANE_TYPE_STRING) == 0)
{
child->get_value("cur", sv);
}
val = &sv[0];
2023-09-09 10:09:20 +00:00
ret = obj->compare_[expr].compare(child, val, &obj->compare_[expr].val1[0], &obj->compare_[expr].val2[0]) ^ obj->compare_[expr].not_op;
child->release();
}
}
return ret;
}
void device_option::clear(void)
{
if (origin_)
origin_->release();
if (now_)
now_->release();
origin_ = now_ = nullptr;
master_opts_.clear();
compare_.clear();
for (auto& v : slaver_)
delete v.second;
slaver_.clear();
for (auto& v : range_value_)
delete v.second;
range_value_.clear();
}
void device_option::init_depends(gb_json* opt)
{
gb_json* range = nullptr;
std::string dpnd("");
if (opt->get_value("depend", dpnd) && !dpnd.empty())
{
simple_logic* logic = new simple_logic();
int pos = 0;
if (logic->parse(dpnd.c_str(), &pos, &device_option::init_condition, this))
slaver_[opt->key().c_str()] = logic;
else
delete logic;
}
// values ...
opt->get_value("range", range);
if (range)
{
range_value* val = new range_value();
opt->get_value("type", dpnd);
if (val->set_value(range, dpnd.c_str(), this))
range_value_[opt->key().c_str()] = val;
else
delete val;
range->release();
}
}
gb_json* device_option::copy_opt(gb_json* from)
{
std::string text(from->to_string());
gb_json* to = new gb_json();
if (!to->attach_text(&text[0]))
{
to->release();
to = nullptr;
}
else
{
std::string val("");
to->key() = from->key();
// 1: language changed ... (title, description, string-list)
if (to->get_value("title", val))
to->set_value("title", from_default_language(val.c_str()));
if (to->get_value("desc", val))
to->set_value("desc", from_default_language(val.c_str()));
// 2: enabled ...
if (slaver_.count(to->key()))
to->set_value("enabled", slaver_[to->key()]->value(&device_option::calc_simple_logic_expression, this));
// 3: range value ...
if (range_value_.count(to->key()))
{
gb_json* src = nullptr, * dst = nullptr;
from->get_value("range", src);
to->get_value("range", dst);
if (src && dst)
{
dst->clear(src->is_array());
2023-09-09 10:09:20 +00:00
dst->key() = src->key();
to->get_value("type", val);
if (val == JSON_SANE_TYPE_BOOL)
{
if (dst->is_array())
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
for (int i = 0; i < range_value_[to->key()]->count(); ++i)
{
if (!val.empty())
*dst += *(bool*)&val[0];
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
}
}
else
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("min", *(bool*)&val[0]);
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("max", *(bool*)&val[0]);
}
}
else if (val == JSON_SANE_TYPE_INT)
{
if (dst->is_array())
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
for (int i = 0; i < range_value_[to->key()]->count(); ++i)
{
if (!val.empty())
*dst += *(int*)&val[0];
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
}
}
else
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("min", *(int*)&val[0]);
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("max", *(int*)&val[0]);
}
}
else if (val == JSON_SANE_TYPE_FIXED)
{
if (dst->is_array())
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
for (int i = 0; i < range_value_[to->key()]->count(); ++i)
{
if (!val.empty())
*dst += *(double*)&val[0];
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
}
}
else
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("min", *(double*)&val[0]);
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("max", *(double*)&val[0]);
}
}
else if (val == JSON_SANE_TYPE_STRING)
{
if (dst->is_array())
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
for(int i = 0; i < range_value_[to->key()]->count(); ++i)
{
if(!val.empty())
*dst += from_default_language(val.c_str());
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
}
}
else
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("min", from_default_language(val.c_str()));
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("max", from_default_language(val.c_str()));
}
}
}
if (src)
src->release();
if (dst)
dst->release();
}
}
return to;
}
bool device_option::to_now(bool init)
{
if (!origin_)
return false;
2023-09-09 10:09:20 +00:00
gb_json* from = nullptr, * to = nullptr, * tmp = now_; // new gb_json();
2023-09-09 10:09:20 +00:00
now_ = new gb_json();
from = origin_->first_child();
while (from)
{
std::string name(from->key());
if (init)
init_depends(from);
to = copy_opt(from);
from->release();
if (to)
{
2023-09-09 10:09:20 +00:00
// copy cur value ...
if (tmp)
{
gb_json* now = nullptr;
tmp->get_value(to->key().c_str(), now);
if (now)
{
std::string type("");
now->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
{
bool v = false;
now->get_value("cur", v);
to->set_value("cur", v);
}
else if (type == JSON_SANE_TYPE_INT)
{
int v = 0;
now->get_value("cur", v);
to->set_value("cur", v);
}
else if (type == JSON_SANE_TYPE_FIXED)
{
double v = .0f;
now->get_value("cur", v);
to->set_value("cur", v);
}
else if (type == JSON_SANE_TYPE_STRING)
{
std::string v("");
now->get_value("cur", v);
to->set_value("cur", v.c_str());
}
now->release();
}
}
now_->set_value(name.c_str(), to);
to->release();
from = origin_->next_child();
}
else
{
2023-09-09 10:09:20 +00:00
now_->release();
now_ = nullptr;
break;
}
}
2023-09-09 10:09:20 +00:00
if (tmp)
tmp->release();
return now_ != nullptr;
}
std::string device_option::option_value(gb_json* jsn, bool def_val)
{
std::string type(""), key(def_val ? "default" : "cur");
jsn->get_value("type", type);
if (type == "bool")
{
bool v = false;
jsn->get_value(key.c_str(), v);
type = std::string((char*)&v, sizeof(v));
}
else if (type == "int")
{
int v = 0;
jsn->get_value(key.c_str(), v);
type = std::string((char*)&v, sizeof(v));
}
else if (type == "float")
{
double v = .0f;
jsn->get_value(key.c_str(), v);
type = std::string((char*)&v, sizeof(v));
}
else if (type == "string")
{
if (!jsn->get_value(key.c_str(), type))
type = "";
}
return std::move(type);
}
bool device_option::init(const char* opt_json)
{
bool ret = false;
std::string text(opt_json);
clear();
origin_ = new gb_json();
if (origin_->attach_text(&text[0]))
{
text.clear();
ret = to_now(true);
if (!ret)
clear();
}
else
{
clear();
}
return ret;
}
bool device_option::refine_data(const char* name, void* value)
{
bool refined = false;
gb_json* child = nullptr;
now_->get_value(name, child);
if (child)
{
std::string type("");
child->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
{
refined = refine_data_to_range<bool, bool>(child, value, copy_simple_type<bool, bool>);
}
else if (type == JSON_SANE_TYPE_INT)
{
refined = refine_data_to_range<int, int>(child, value, copy_simple_type<int, int>);
}
else if (type == JSON_SANE_TYPE_FIXED)
{
refined = refine_data_to_range<double, double>(child, value, copy_simple_type<double, double>);
}
else if (type == JSON_SANE_TYPE_STRING)
{
2023-09-09 10:09:20 +00:00
refined = refine_string_data(child, value);
}
child->release();
}
return refined;
}
int device_option::update_data(const char* name, void* value)
{
if (!name)
{
to_now(false);
return SCANNER_ERR_RELOAD_OPT_PARAM;
}
else if(now_)
{
std::string type("");
gb_json* child = nullptr;
now_->get_value(name, child);
if (child)
{
child->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
child->set_value("cur", *(bool*)value);
else if (type == JSON_SANE_TYPE_INT)
child->set_value("cur", *(int*)value);
else if (type == JSON_SANE_TYPE_FIXED)
child->set_value("cur", *(double*)value);
else if (type == JSON_SANE_TYPE_STRING)
child->set_value("cur", (char*)value);
child->release();
if (std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end())
{
to_now(false);
return SCANNER_ERR_RELOAD_OPT_PARAM;
}
}
}
return SCANNER_ERR_OK;
}
std::string device_option::get_option_value_type(const char* name)
{
std::string value("");
if (now_)
{
gb_json* child = nullptr;
now_->get_value(name, child);
if (child)
{
child->get_value("type", value);
child->release();
}
}
return std::move(value);
}
std::string device_option::get_option_value(const char* name, int type)
{
std::string value("");
if (now_)
{
if (!name)
{
value = now_->to_string();
}
else
{
gb_json* child = nullptr;
now_->get_value(name, child);
if (child)
{
if (type == OPT_VAL_JSON)
value = child->to_string();
else
value = device_option::option_value(child, type == OPT_VAL_DEFAULT);
child->release();
}
}
}
return std::move(value);
}