2023-09-08 09:42:40 +00:00
|
|
|
|
#include "device_opt.h"
|
|
|
|
|
|
|
|
|
|
#include <huagao/hgscanner_error.h>
|
2023-09-22 01:42:37 +00:00
|
|
|
|
#include "../../../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
2023-10-31 06:51:14 +00:00
|
|
|
|
#include "../../../sdk/hginclude/base_opt.h"
|
2023-09-08 09:42:40 +00:00
|
|
|
|
#include <lang/app_language.h>
|
2023-09-23 01:15:57 +00:00
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <algorithm>
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// image-processing jsons ...
|
|
|
|
|
|
2023-09-09 10:09:20 +00:00
|
|
|
|
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-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
if (v < vl)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
strcpy((char*)value, vl.c_str());
|
2023-09-08 09:42:40 +00:00
|
|
|
|
refined = true;
|
|
|
|
|
}
|
2023-09-09 10:09:20 +00:00
|
|
|
|
else if (range->get_value("max", vu))
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
if (v > vu)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
strcpy((char*)value, vu.c_str());
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
if (v == vl)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
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))
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
refined = true;
|
2023-09-09 10:09:20 +00:00
|
|
|
|
strcpy((char*)value, vl.c_str());
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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 "";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
static struct
|
|
|
|
|
{
|
|
|
|
|
std::string name;
|
|
|
|
|
std::string title; // in UTF8
|
|
|
|
|
}g_known_group_with_sn[] = { {"base", "\xE5\x9F\xBA\xE6\x9C\xAC\xE8\xAE\xBE\xE7\xBD\xAE"}
|
|
|
|
|
, {"bright", "\xE4\xBA\xAE\xE5\xBA\xA6"}
|
|
|
|
|
, {"imgp", "\xE5\x9B\xBE\xE5\x83\x8F\xE5\xA4\x84\xE7\x90\x86"}
|
2023-09-23 01:15:57 +00:00
|
|
|
|
, {"feeder", "\xE9\x80\x81\xE7\xBA\xB8\xE6\x96\xB9\xE5\xBC\x8F\xE8\xAE\xBE\xE7\xBD\xAE"} // <20><><EFBFBD>ã<EFBFBD>\xE8\xAE\xBE\xE7\xBD\xAE
|
2023-09-13 03:20:51 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// 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();
|
2023-10-16 07:52:16 +00:00
|
|
|
|
if (!jsn)
|
|
|
|
|
{
|
|
|
|
|
// consistant value, and type is name ...
|
|
|
|
|
CONDVAL cv;
|
|
|
|
|
|
|
|
|
|
cv.logic = nullptr;
|
|
|
|
|
cv.value = type;
|
|
|
|
|
vals_.push_back(cv);
|
|
|
|
|
parent_ = parent;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2023-10-16 07:52:16 +00:00
|
|
|
|
std::string device_option::condition_value::value(bool(*compare)(const char*, void*), void* param)
|
|
|
|
|
{
|
|
|
|
|
if (parent_)
|
2023-10-31 06:51:14 +00:00
|
|
|
|
return parent_->get_option_value(vals_[0].value.c_str(), SANE_ACTION_GET_VALUE);
|
2023-10-16 07:52:16 +00:00
|
|
|
|
|
|
|
|
|
for (auto& v : vals_)
|
|
|
|
|
{
|
|
|
|
|
if (!v.logic)
|
|
|
|
|
return v.value;
|
|
|
|
|
else if (v.logic->value(compare, param))
|
|
|
|
|
return v.value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "";
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
bool device_option::range_value::set_value(gb_json* jsn, const char* type, device_option* parent) // jsn contains all range object
|
|
|
|
|
{
|
|
|
|
|
bool ret = true;
|
|
|
|
|
|
2023-10-16 07:52:16 +00:00
|
|
|
|
parent->depend_opts_[jsn->key()];
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
device_option::device_option(std::function<bool(int)> user_priv, std::function<void(const char*)> log) : origin_(nullptr), now_(nullptr)
|
|
|
|
|
, user_(user_priv), log_(log)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-02 09:07:28 +00:00
|
|
|
|
bool device_option::is_string_function(const char* expr, std::string& name, int& start, int& cnt)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
std::string exp(expr);
|
|
|
|
|
size_t pos = exp.find(".");
|
|
|
|
|
|
|
|
|
|
cnt = 0;
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
name = exp.substr(0, pos++);
|
|
|
|
|
exp.erase(0, pos);
|
2023-11-04 01:44:01 +00:00
|
|
|
|
if (exp.find("left(") == 0)
|
2023-11-02 09:07:28 +00:00
|
|
|
|
{
|
|
|
|
|
exp.erase(0, 5);
|
|
|
|
|
start = 0;
|
|
|
|
|
cnt = atoi(exp.c_str());
|
|
|
|
|
pos = 0;
|
|
|
|
|
}
|
2023-11-04 01:44:01 +00:00
|
|
|
|
else if (exp.find("right(") == 0)
|
2023-11-02 09:07:28 +00:00
|
|
|
|
{
|
|
|
|
|
exp.erase(0, 6);
|
|
|
|
|
start = -1 * atoi(exp.c_str());
|
|
|
|
|
cnt = -1;
|
|
|
|
|
pos = 0;
|
|
|
|
|
}
|
2023-11-04 01:44:01 +00:00
|
|
|
|
else if (exp.find("mid(") == 0)
|
2023-11-02 09:07:28 +00:00
|
|
|
|
{
|
|
|
|
|
exp.erase(0, 4);
|
|
|
|
|
start = atoi(exp.c_str());
|
|
|
|
|
pos = exp.find(",");
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
exp.erase(0, pos + 1);
|
|
|
|
|
cnt = atoi(exp.c_str());
|
|
|
|
|
pos = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pos == 0)
|
|
|
|
|
{
|
2023-11-04 01:44:01 +00:00
|
|
|
|
pos = exp.find(")");
|
2023-11-02 09:07:28 +00:00
|
|
|
|
ret = pos != std::string::npos && (cnt > 0 || cnt == -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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)
|
|
|
|
|
{
|
2023-11-02 09:07:28 +00:00
|
|
|
|
const char* opers[] = { ">", "<", "!", "=", "." }, * tag = nullptr, * dot = strstr(expr, ".");
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
for (auto& v : opers)
|
|
|
|
|
{
|
|
|
|
|
tag = strstr(expr, v);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
if (tag)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!tag)
|
|
|
|
|
return false;
|
|
|
|
|
|
2023-11-02 09:07:28 +00:00
|
|
|
|
if (dot && dot < tag) // is mode.!enable ?
|
|
|
|
|
{
|
|
|
|
|
tag = dot;
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2023-11-02 09:07:28 +00:00
|
|
|
|
// substr function ...
|
2023-11-04 01:44:01 +00:00
|
|
|
|
if (strstr(tag, "left(") || strstr(tag, "right(") || strstr(tag, "mid("))
|
2023-11-02 09:07:28 +00:00
|
|
|
|
{
|
2023-11-04 01:44:01 +00:00
|
|
|
|
const char* end = nullptr, *start = strstr(tag, "(");
|
|
|
|
|
int l = string_util::find_end_of_pair(start + 1, '(', ')');
|
|
|
|
|
bool ret = start[++l] == ')';
|
2023-11-02 09:07:28 +00:00
|
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
2023-11-03 10:03:22 +00:00
|
|
|
|
std::string exp(calc.name + (start + l + 1)),
|
|
|
|
|
name1(tag, start + l - tag + 1);
|
2023-11-02 09:07:28 +00:00
|
|
|
|
name1.insert(0, calc.name + ".");
|
|
|
|
|
ret = device_option::parse_simple_logic_expression(root, exp.c_str(), name, calc);
|
|
|
|
|
if (ret)
|
|
|
|
|
calc.name = std::move(name1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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-11-02 09:07:28 +00:00
|
|
|
|
bool substr = false;
|
|
|
|
|
int start = 0, cnt = 0;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
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);
|
2023-11-02 09:07:28 +00:00
|
|
|
|
if (!child)
|
|
|
|
|
{
|
|
|
|
|
// check string function ...
|
|
|
|
|
std::string name("");
|
|
|
|
|
substr = device_option::is_string_function(expr, name, start, cnt);
|
|
|
|
|
if (substr)
|
|
|
|
|
{
|
|
|
|
|
if (obj->now_)
|
|
|
|
|
obj->now_->get_value(name.c_str(), child);
|
|
|
|
|
else
|
|
|
|
|
obj->origin_->get_value(name.c_str(), child);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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);
|
2023-11-02 09:07:28 +00:00
|
|
|
|
if (substr)
|
|
|
|
|
{
|
|
|
|
|
if (start < 0)
|
|
|
|
|
start = sv.length() + start;
|
|
|
|
|
if (start > 0 && start < sv.length())
|
|
|
|
|
sv.erase(0, start);
|
|
|
|
|
if (cnt > 0 && cnt < sv.length())
|
|
|
|
|
sv.erase(cnt);
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
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;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
void device_option::clear_for_reconstruct(void)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
if (now_)
|
|
|
|
|
now_->release();
|
2023-10-31 06:51:14 +00:00
|
|
|
|
now_ = nullptr;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
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();
|
2023-09-13 08:07:13 +00:00
|
|
|
|
|
|
|
|
|
for (auto& v : init_value_)
|
|
|
|
|
delete v.second;
|
|
|
|
|
init_value_.clear();
|
2023-09-25 08:47:05 +00:00
|
|
|
|
|
|
|
|
|
for (auto& v : support_value_)
|
|
|
|
|
delete v.second;
|
|
|
|
|
support_value_.clear();
|
2023-10-16 07:52:16 +00:00
|
|
|
|
|
|
|
|
|
depend_opts_.clear();
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
2023-09-13 03:20:51 +00:00
|
|
|
|
gb_json* device_option::group_opt(const char* title)
|
|
|
|
|
{
|
|
|
|
|
gb_json* jsn = new gb_json();
|
|
|
|
|
|
|
|
|
|
jsn->set_value("title", title);
|
|
|
|
|
jsn->set_value("type", "group");
|
|
|
|
|
|
|
|
|
|
return jsn;
|
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
int device_option::next_group(int start)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
for (; start < origin_->children(); ++start)
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = origin_->child(start);
|
|
|
|
|
std::string str("");
|
|
|
|
|
|
|
|
|
|
child->get_value("type", str);
|
|
|
|
|
child->release();
|
|
|
|
|
|
|
|
|
|
if (str == JSON_SANE_TYPE_GROUP)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return start;
|
|
|
|
|
}
|
|
|
|
|
int device_option::insert_group(const char* name, const char* title)
|
|
|
|
|
{
|
|
|
|
|
gb_json* group = nullptr;
|
|
|
|
|
int ind = origin_->children();
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
origin_->get_value(name, group);
|
|
|
|
|
if (group)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
ind = origin_->index(group);
|
|
|
|
|
group->release();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : g_known_group_with_sn)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
if (v.name == name)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
title = v.title.c_str();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gb_json* child = nullptr;
|
|
|
|
|
origin_->get_value(v.name.c_str(), child);
|
|
|
|
|
if (child)
|
|
|
|
|
{
|
|
|
|
|
if (group)
|
|
|
|
|
group->release();
|
|
|
|
|
group = child;
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
|
|
|
|
|
if (group)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
ind = origin_->index(group) + 1;
|
|
|
|
|
group->release();
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
ind = 0;
|
|
|
|
|
ind = next_group(ind);
|
|
|
|
|
group = group_opt(title);
|
|
|
|
|
origin_->insert(ind, name, group);
|
|
|
|
|
group->release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ind;
|
|
|
|
|
}
|
|
|
|
|
void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const char* group)
|
|
|
|
|
{
|
|
|
|
|
// first compare version, reserve higher version
|
|
|
|
|
// second compare position, replace with last insertion
|
|
|
|
|
// last, sort by position
|
|
|
|
|
gb_json* existing = nullptr;
|
|
|
|
|
|
|
|
|
|
origin_->get_value(opt->key().c_str(), existing);
|
|
|
|
|
if (existing)
|
|
|
|
|
{
|
|
|
|
|
int vo = 0, vn = 0;
|
|
|
|
|
opt->get_value("ver", vn);
|
|
|
|
|
existing->get_value("ver", vo);
|
|
|
|
|
if (vn > vo)
|
|
|
|
|
{
|
|
|
|
|
// replace and discard all following options ...
|
|
|
|
|
write_log("SANE-OPT: use %s::%s(ver: %d) replaced with %s::%s(ver: %d)\n", src_[existing->key()]->from().c_str(), existing->key().c_str(), vo
|
|
|
|
|
, from->from().c_str(), opt->key().c_str(), vn);
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
vo = origin_->index(existing);
|
|
|
|
|
origin_->remove(vo);
|
|
|
|
|
if (src_.count(existing->key()))
|
|
|
|
|
{
|
|
|
|
|
src_[existing->key()]->release();
|
|
|
|
|
src_.erase(existing->key());
|
|
|
|
|
}
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
origin_->insert(vo, opt->key().c_str(), opt);
|
|
|
|
|
opt->add_ref();
|
|
|
|
|
|
|
|
|
|
src_[opt->key()] = from;
|
|
|
|
|
from->add_ref();
|
|
|
|
|
}
|
|
|
|
|
else if (vn == vo)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
// insert into following queue ...
|
|
|
|
|
write_log("SANE-OPT: inserting %s::%s to provider queue ...\n", from->from().c_str(), opt->key().c_str());
|
|
|
|
|
opt->get_value("pos", vn);
|
|
|
|
|
existing->get_value("pos", vo);
|
|
|
|
|
if (vo < vn)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
sane_opt_provider* prev = src_[existing->key()],
|
|
|
|
|
*que = src_[existing->key()]->get_following(existing->key().c_str());
|
|
|
|
|
|
|
|
|
|
prev->add_ref();
|
|
|
|
|
while (que)
|
|
|
|
|
{
|
|
|
|
|
std::string text(que->get_opt_json());
|
|
|
|
|
gb_json* jsn = new gb_json(), *child = nullptr;
|
|
|
|
|
|
|
|
|
|
jsn->attach_text(&text[0]);
|
|
|
|
|
jsn->get_value(existing->key().c_str(), child);
|
|
|
|
|
if (child)
|
|
|
|
|
{
|
|
|
|
|
child->get_value("ver", vo);
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
jsn->release();
|
|
|
|
|
if (vo >= vn)
|
|
|
|
|
break;
|
|
|
|
|
prev->release();
|
|
|
|
|
prev = que;
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
que = que->get_following(existing->key().c_str());
|
|
|
|
|
}
|
|
|
|
|
prev->set_following_provider(opt->key().c_str(), from);
|
|
|
|
|
if (vo == vn)
|
2023-09-13 03:20:51 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
// replace ...
|
|
|
|
|
if(que)
|
|
|
|
|
{
|
|
|
|
|
sane_opt_provider* next = que->get_following(opt->key().c_str());
|
|
|
|
|
que->set_following_provider(opt->key().c_str(), nullptr);
|
|
|
|
|
if (next)
|
|
|
|
|
{
|
|
|
|
|
from->set_following_provider(opt->key().c_str(), next);
|
|
|
|
|
next->release();
|
|
|
|
|
}
|
|
|
|
|
que->release(); // release get_following reference
|
|
|
|
|
}
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// insert ...
|
|
|
|
|
from->set_following_provider(opt->key().c_str(), que);
|
|
|
|
|
if (que)
|
|
|
|
|
que->release();
|
|
|
|
|
}
|
|
|
|
|
prev->release();
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else if (vo > vn)
|
|
|
|
|
{
|
|
|
|
|
from->set_following_provider(opt->key().c_str(), src_[existing->key()]);
|
|
|
|
|
src_[existing->key()]->release();
|
|
|
|
|
src_[opt->key()] = from;
|
|
|
|
|
from->add_ref();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// replace ...
|
|
|
|
|
vo = origin_->index(existing);
|
|
|
|
|
origin_->remove(vo);
|
|
|
|
|
if (src_.count(existing->key()))
|
|
|
|
|
{
|
|
|
|
|
sane_opt_provider* next = src_[existing->key()]->get_following(existing->key().c_str());
|
|
|
|
|
src_[existing->key()]->set_following_provider(existing->key().c_str(), nullptr);
|
|
|
|
|
src_[existing->key()]->release();
|
|
|
|
|
src_.erase(existing->key());
|
|
|
|
|
while (next)
|
|
|
|
|
{
|
|
|
|
|
sane_opt_provider* next1 = next->get_following(existing->key().c_str());
|
|
|
|
|
next->set_following_provider(existing->key().c_str(), nullptr);
|
|
|
|
|
next->release();
|
|
|
|
|
next = next1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
origin_->insert(vo, opt->key().c_str(), opt);
|
|
|
|
|
opt->add_ref();
|
|
|
|
|
|
|
|
|
|
src_[opt->key()] = from;
|
|
|
|
|
from->add_ref();
|
|
|
|
|
}
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
write_log("SANE-OPT: option '%s' queue: %s", opt->key().c_str(), src_[opt->key().c_str()]->from().c_str());
|
|
|
|
|
|
|
|
|
|
sane_opt_provider* next = src_[opt->key().c_str()]->get_following(opt->key().c_str());
|
|
|
|
|
while (next)
|
|
|
|
|
{
|
|
|
|
|
write_log(" -> %s", next->from().c_str());
|
|
|
|
|
|
|
|
|
|
sane_opt_provider* next1 = next;
|
|
|
|
|
next = next->get_following(opt->key().c_str());
|
|
|
|
|
next1->release();
|
|
|
|
|
}
|
|
|
|
|
write_log("\n");
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// discard new option ...
|
|
|
|
|
write_log("SANE-OPT: discard %s::%s(ver: %d) for %s::%s(ver: %d) existed!\n", from->from().c_str(), opt->key().c_str(), vn
|
|
|
|
|
, src_[existing->key()]->from().c_str(), existing->key().c_str(), vo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
existing->release();
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int index = -1;
|
|
|
|
|
|
|
|
|
|
if (group)
|
|
|
|
|
index = insert_group(group, group);
|
|
|
|
|
index = next_group(index + 1);
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
origin_->insert(index, opt->key().c_str(), opt);
|
|
|
|
|
src_[opt->key()] = from;
|
|
|
|
|
from->add_ref();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool device_option::arrange_raw_json(sane_opt_provider* sop)
|
|
|
|
|
{
|
|
|
|
|
std::vector<gb_json*> ungroup;
|
|
|
|
|
std::map<std::string, std::vector<gb_json*>> ingroup;
|
|
|
|
|
gb_json* jsn = new gb_json(), *child = nullptr;
|
|
|
|
|
std::string text(sop->get_opt_json()), str("");
|
|
|
|
|
bool ret = jsn->attach_text(&text[0]);
|
|
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
if (!origin_)
|
|
|
|
|
origin_ = new gb_json();
|
|
|
|
|
|
|
|
|
|
text.clear();
|
|
|
|
|
child = jsn->first_child();
|
|
|
|
|
while (child)
|
|
|
|
|
{
|
|
|
|
|
child->get_value("type", str);
|
|
|
|
|
if (str != JSON_SANE_TYPE_GROUP) // omit group
|
|
|
|
|
{
|
|
|
|
|
child->get_value("group", str);
|
|
|
|
|
insert_option(child, sop, str.empty() ? nullptr : str.c_str());
|
|
|
|
|
}
|
|
|
|
|
child->release();
|
|
|
|
|
child = jsn->next_child();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
jsn->release();
|
|
|
|
|
|
|
|
|
|
return ret;
|
2023-09-13 03:20:51 +00:00
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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))
|
2023-09-13 08:07:13 +00:00
|
|
|
|
range_value_[opt->key()] = val;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
else
|
|
|
|
|
delete val;
|
|
|
|
|
|
|
|
|
|
range->release();
|
|
|
|
|
}
|
2023-09-13 08:07:13 +00:00
|
|
|
|
|
|
|
|
|
// default:
|
|
|
|
|
range = nullptr;
|
|
|
|
|
opt->get_value("default", range);
|
|
|
|
|
opt->get_value("type", dpnd);
|
|
|
|
|
if (range)
|
|
|
|
|
{
|
2023-09-14 03:28:21 +00:00
|
|
|
|
condition_value* rv = new condition_value();
|
2023-09-13 08:07:13 +00:00
|
|
|
|
if (rv->set_value(range, dpnd.c_str(), this))
|
|
|
|
|
init_value_[opt->key()] = rv;
|
|
|
|
|
else
|
|
|
|
|
delete rv;
|
|
|
|
|
|
|
|
|
|
range->release();
|
|
|
|
|
}
|
2023-09-25 08:47:05 +00:00
|
|
|
|
|
|
|
|
|
// visible
|
|
|
|
|
range = nullptr;
|
|
|
|
|
opt->get_value("visible", range);
|
|
|
|
|
if(range)
|
|
|
|
|
{
|
|
|
|
|
condition_value* v = new condition_value();
|
|
|
|
|
if (v->set_value(range, JSON_SANE_TYPE_INT, this))
|
|
|
|
|
support_value_[opt->key()] = v;
|
|
|
|
|
else
|
|
|
|
|
delete v;
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
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));
|
|
|
|
|
|
2023-09-13 08:07:13 +00:00
|
|
|
|
// 3: default value ...
|
|
|
|
|
if (init_value_.count(to->key()))
|
|
|
|
|
{
|
2023-09-14 03:28:21 +00:00
|
|
|
|
std::string val(init_value_[to->key()]->value(&device_option::calc_simple_logic_expression, this));
|
|
|
|
|
std::string type("");
|
|
|
|
|
to->get_value("type", type);
|
|
|
|
|
|
|
|
|
|
if (type == JSON_SANE_TYPE_BOOL)
|
|
|
|
|
to->set_value("default", *(bool*)val.c_str());
|
|
|
|
|
else if(type == JSON_SANE_TYPE_INT)
|
|
|
|
|
to->set_value("default", *(int*)val.c_str());
|
|
|
|
|
else if(type == JSON_SANE_TYPE_FIXED)
|
|
|
|
|
to->set_value("default", *(double*)val.c_str());
|
|
|
|
|
else if(type == JSON_SANE_TYPE_STRING)
|
|
|
|
|
to->set_value("default", (const wchar_t*)val.c_str());
|
2023-09-13 08:07:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4: range value ...
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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();
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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]);
|
2023-10-31 10:04:26 +00:00
|
|
|
|
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
|
|
|
|
|
dst->set_value("step", *(bool*)&val[0]);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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]);
|
2023-10-31 10:04:26 +00:00
|
|
|
|
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
|
|
|
|
|
dst->set_value("step", *(int*)&val[0]);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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]);
|
2023-10-31 10:04:26 +00:00
|
|
|
|
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
|
|
|
|
|
dst->set_value("step", *(double*)&val[0]);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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()));
|
2023-10-31 10:04:26 +00:00
|
|
|
|
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
|
|
|
|
|
dst->set_value("step", from_default_language(val.c_str()));
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src)
|
|
|
|
|
src->release();
|
|
|
|
|
if (dst)
|
|
|
|
|
dst->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return to;
|
|
|
|
|
}
|
2023-09-25 08:47:05 +00:00
|
|
|
|
int device_option::visibility(gb_json* jsn)
|
|
|
|
|
{
|
|
|
|
|
int visb = OPT_VISIBLE_ALL;
|
|
|
|
|
|
|
|
|
|
if (!jsn->get_value("visible", visb))
|
|
|
|
|
{
|
|
|
|
|
if (support_value_.count(jsn->key()))
|
|
|
|
|
{
|
|
|
|
|
std::string val(support_value_[jsn->key()]->value(&device_option::calc_simple_logic_expression, this));
|
|
|
|
|
visb = *(int*)&val[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return visb;
|
|
|
|
|
}
|
2023-09-14 09:53:17 +00:00
|
|
|
|
bool device_option::to_now(bool init, bool* changed)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
if (!origin_)
|
|
|
|
|
return false;
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
gb_json* from = nullptr, * to = nullptr, * tmp = new gb_json();
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
from = origin_->first_child();
|
|
|
|
|
while (from)
|
|
|
|
|
{
|
|
|
|
|
std::string name(from->key());
|
|
|
|
|
|
|
|
|
|
if (init)
|
|
|
|
|
init_depends(from);
|
|
|
|
|
|
2023-09-25 08:47:05 +00:00
|
|
|
|
int pub = visibility(from);
|
|
|
|
|
if (pub == OPT_VISIBLE_HIDE || pub == OPT_VISIBLE_NOT_SUPPORT)
|
2023-09-21 03:23:38 +00:00
|
|
|
|
{
|
2023-09-25 08:47:05 +00:00
|
|
|
|
if (pub == OPT_VISIBLE_NOT_SUPPORT || !user_ || !user_(USER_PRIVILEGE_DEVLOPER))
|
2023-09-21 03:23:38 +00:00
|
|
|
|
{
|
|
|
|
|
from->release();
|
|
|
|
|
from = origin_->next_child();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
to = copy_opt(from);
|
|
|
|
|
from->release();
|
|
|
|
|
if (to)
|
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
// copy cur value ...
|
2023-09-13 03:20:51 +00:00
|
|
|
|
if (now_)
|
2023-09-09 10:09:20 +00:00
|
|
|
|
{
|
|
|
|
|
gb_json* now = nullptr;
|
2023-09-13 03:20:51 +00:00
|
|
|
|
now_->get_value(to->key().c_str(), now);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
if (now)
|
|
|
|
|
{
|
|
|
|
|
std::string type("");
|
|
|
|
|
now->get_value("type", type);
|
|
|
|
|
if (type == JSON_SANE_TYPE_BOOL)
|
|
|
|
|
{
|
|
|
|
|
bool v = false;
|
|
|
|
|
now->get_value("cur", v);
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refine_data_to_range<bool>(to, &v);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
to->set_value("cur", v);
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_INT)
|
|
|
|
|
{
|
|
|
|
|
int v = 0;
|
|
|
|
|
now->get_value("cur", v);
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refine_data_to_range<int>(to, &v);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
to->set_value("cur", v);
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_FIXED)
|
|
|
|
|
{
|
|
|
|
|
double v = .0f;
|
|
|
|
|
now->get_value("cur", v);
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refine_data_to_range<double>(to, &v);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
to->set_value("cur", v);
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_STRING)
|
|
|
|
|
{
|
|
|
|
|
std::string v("");
|
2023-09-14 09:53:17 +00:00
|
|
|
|
int size = 0, s1 = 0;
|
|
|
|
|
char *vv = nullptr;
|
|
|
|
|
|
|
|
|
|
to->get_value("size", size);
|
|
|
|
|
now->get_value("size", s1);
|
|
|
|
|
if (size < s1)
|
|
|
|
|
size = s1;
|
|
|
|
|
vv = new char[size + 4];
|
|
|
|
|
memset(vv, 0, size + 4);
|
2023-09-09 10:09:20 +00:00
|
|
|
|
now->get_value("cur", v);
|
2023-09-14 09:53:17 +00:00
|
|
|
|
strcpy(vv, v.c_str());
|
|
|
|
|
refine_string_data(to, vv);
|
|
|
|
|
to->set_value("cur", vv);
|
|
|
|
|
delete[] vv;
|
2023-09-09 10:09:20 +00:00
|
|
|
|
}
|
|
|
|
|
now->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
|
|
|
|
|
tmp->set_value(name.c_str(), to);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
to->release();
|
|
|
|
|
|
|
|
|
|
from = origin_->next_child();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-09-13 03:20:51 +00:00
|
|
|
|
tmp->release();
|
|
|
|
|
tmp = nullptr;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-14 09:53:17 +00:00
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
if (!now_ || !tmp)
|
|
|
|
|
*changed = true;
|
|
|
|
|
else
|
|
|
|
|
*changed = *now_ != *tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
if (now_)
|
|
|
|
|
now_->release();
|
|
|
|
|
now_ = tmp;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
std::string device_option::trans_group(const char* utf8, bool to_title)
|
|
|
|
|
{
|
|
|
|
|
if (to_title)
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : g_known_group_with_sn)
|
|
|
|
|
{
|
|
|
|
|
if (v.name == utf8)
|
|
|
|
|
return v.title;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : g_known_group_with_sn)
|
|
|
|
|
{
|
|
|
|
|
if (v.title == utf8)
|
|
|
|
|
return v.name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return utf8;
|
|
|
|
|
}
|
|
|
|
|
std::string device_option::get_group(int ind, bool title)
|
|
|
|
|
{
|
|
|
|
|
if (ind >= 0 && ind < _countof(g_known_group_with_sn))
|
|
|
|
|
return title ? g_known_group_with_sn[ind].title : g_known_group_with_sn[ind].name;
|
|
|
|
|
else
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
void device_option::clear(void)
|
|
|
|
|
{
|
|
|
|
|
clear_for_reconstruct();
|
|
|
|
|
|
|
|
|
|
if (origin_)
|
|
|
|
|
origin_->release();
|
|
|
|
|
origin_ = nullptr;
|
|
|
|
|
|
|
|
|
|
for (auto& v : src_)
|
|
|
|
|
v.second->release();
|
|
|
|
|
src_.clear();
|
|
|
|
|
}
|
|
|
|
|
bool device_option::add(sane_opt_provider* sop)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
clear_for_reconstruct();
|
|
|
|
|
if (arrange_raw_json(sop))
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
2023-09-14 09:53:17 +00:00
|
|
|
|
ret = to_now(true, nullptr);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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)
|
|
|
|
|
{
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refined = refine_data_to_range<bool>(child, value);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_INT)
|
|
|
|
|
{
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refined = refine_data_to_range<int>(child, value);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_FIXED)
|
|
|
|
|
{
|
2023-10-16 07:52:16 +00:00
|
|
|
|
refined = refine_data_to_range<double>(child, value);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_STRING)
|
|
|
|
|
{
|
2023-09-09 10:09:20 +00:00
|
|
|
|
refined = refine_string_data(child, value);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return refined;
|
|
|
|
|
}
|
2023-10-31 10:04:26 +00:00
|
|
|
|
int device_option::update_data(const char* name, void* value, bool reorder_if_need)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
int err = SCANNER_ERR_NO_DATA;
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
if (!name)
|
|
|
|
|
{
|
2023-09-14 09:53:17 +00:00
|
|
|
|
to_now(false, nullptr);
|
2023-10-31 06:51:14 +00:00
|
|
|
|
err = SCANNER_ERR_RELOAD_OPT_PARAM;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
else if(now_)
|
|
|
|
|
{
|
|
|
|
|
std::string type("");
|
|
|
|
|
gb_json* child = nullptr;
|
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
now_->get_value(name, child);
|
|
|
|
|
if (child)
|
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
bool ro = false;
|
|
|
|
|
if (child->get_value("readonly", ro) && ro)
|
2023-09-15 09:53:13 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
child->release();
|
|
|
|
|
|
|
|
|
|
err = SCANNER_ERR_ACCESS_DENIED;
|
2023-09-15 09:53:13 +00:00
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else
|
2023-09-15 09:53:13 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
std::string pre(device_option::option_value(child, false));
|
|
|
|
|
bool changed = false;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
// pass to sane_opt_provider ...
|
|
|
|
|
err = SCANNER_ERR_OK;
|
|
|
|
|
if (src_.count(name))
|
|
|
|
|
err = src_[name]->set_value(name, value);
|
2023-09-14 09:53:17 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
if (err == SCANNER_ERR_OK || err == SCANNER_ERR_NOT_EXACT
|
|
|
|
|
|| err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM)
|
2023-09-14 09:53:17 +00:00
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
child->get_value("type", type);
|
|
|
|
|
if (type == JSON_SANE_TYPE_BOOL)
|
|
|
|
|
{
|
|
|
|
|
child->set_value("cur", *(bool*)value);
|
|
|
|
|
changed = *(bool*)value != *(bool*)pre.c_str();
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_INT)
|
|
|
|
|
{
|
|
|
|
|
child->set_value("cur", *(int*)value);
|
|
|
|
|
changed = *(int*)value != *(int*)pre.c_str();
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_FIXED)
|
|
|
|
|
{
|
|
|
|
|
child->set_value("cur", *(double*)value);
|
|
|
|
|
changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (type == JSON_SANE_TYPE_STRING)
|
|
|
|
|
{
|
|
|
|
|
child->set_value("cur", (char*)value);
|
|
|
|
|
changed = pre != (char*)value;
|
|
|
|
|
}
|
|
|
|
|
child->release();
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-10-31 10:04:26 +00:00
|
|
|
|
if (reorder_if_need && changed && // value has changed
|
2023-10-31 06:51:14 +00:00
|
|
|
|
std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end()) // can affect others
|
|
|
|
|
{
|
|
|
|
|
changed = false;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
changed = false;
|
|
|
|
|
to_now(false, &changed);
|
|
|
|
|
} while (changed);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-10-31 06:51:14 +00:00
|
|
|
|
err = SCANNER_ERR_RELOAD_OPT_PARAM;
|
|
|
|
|
}
|
|
|
|
|
} // provider has processed right
|
|
|
|
|
} // not read-only option
|
|
|
|
|
} // has option named 'name'
|
|
|
|
|
} // has initialized
|
|
|
|
|
|
|
|
|
|
return err;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
2023-10-31 10:04:26 +00:00
|
|
|
|
int device_option::restore(sane_opt_provider* holder)
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = nullptr, * cur = now_;
|
|
|
|
|
|
|
|
|
|
if (cur)
|
|
|
|
|
{
|
|
|
|
|
cur->add_ref();
|
|
|
|
|
child = cur->first_child();
|
|
|
|
|
while (child)
|
|
|
|
|
{
|
|
|
|
|
if (src_.count(child->key()) && src_[child->key()] == holder
|
|
|
|
|
&& is_auto_restore_default(child->key().c_str()))
|
|
|
|
|
{
|
|
|
|
|
std::string val(device_option::option_value(child, true));
|
|
|
|
|
update_data(child->key().c_str(), &val[0], false);
|
|
|
|
|
}
|
|
|
|
|
child->release();
|
|
|
|
|
child = cur->next_child();
|
|
|
|
|
}
|
|
|
|
|
cur->release();
|
|
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
changed = false;
|
|
|
|
|
to_now(false, &changed);
|
|
|
|
|
} while (changed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SCANNER_ERR_RELOAD_OPT_PARAM;
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
int device_option::count(void)
|
|
|
|
|
{
|
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
|
|
|
|
|
|
|
|
|
if (jsn)
|
|
|
|
|
return jsn->children();
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-22 07:43:53 +00:00
|
|
|
|
bool device_option::is_auto_restore_default(const char* name)
|
|
|
|
|
{
|
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_,
|
|
|
|
|
* child = nullptr;
|
|
|
|
|
bool support = true;
|
|
|
|
|
|
|
|
|
|
jsn->get_value(name, child);
|
|
|
|
|
if (child)
|
|
|
|
|
{
|
2023-09-25 08:47:05 +00:00
|
|
|
|
if (!child->get_value("auto", support))
|
|
|
|
|
support = true;
|
|
|
|
|
|
2023-09-22 07:43:53 +00:00
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return support;
|
|
|
|
|
}
|
2023-09-15 09:53:13 +00:00
|
|
|
|
std::string device_option::get_name_by_sane_id(int sane_ind)
|
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
|
|
|
|
|
|
|
|
|
if (sane_ind > 0 && sane_ind - 1 < jsn->children())
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = now_->child(sane_ind - 1);
|
2023-09-22 07:43:53 +00:00
|
|
|
|
//child->get_value("name", value);
|
|
|
|
|
value = child->key();
|
2023-09-15 09:53:13 +00:00
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
std::string device_option::get_option_value_type(const char* name)
|
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
2023-09-15 09:53:13 +00:00
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
if (jsn)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
gb_json* child = nullptr;
|
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
jsn->get_value(name, child);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
if (child)
|
|
|
|
|
{
|
|
|
|
|
child->get_value("type", value);
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
std::string device_option::get_option_value(const char* name, int type, int* size, void* in_data)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
2023-10-16 07:52:16 +00:00
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-10-16 07:52:16 +00:00
|
|
|
|
if (jsn)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
if (!name)
|
|
|
|
|
{
|
2023-10-16 07:52:16 +00:00
|
|
|
|
value = jsn->to_string();
|
2023-09-08 09:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = nullptr;
|
2023-10-31 06:51:14 +00:00
|
|
|
|
bool own_read = false;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-10-16 07:52:16 +00:00
|
|
|
|
jsn->get_value(name, child);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
if (child)
|
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
if (type == SANE_ACTION_GET_ENTIRE_JSON)
|
2023-09-08 09:42:40 +00:00
|
|
|
|
value = child->to_string();
|
2023-10-31 06:51:14 +00:00
|
|
|
|
else if (child->get_value("ownread", own_read) && own_read)
|
|
|
|
|
{
|
|
|
|
|
if (src_.count(name))
|
|
|
|
|
value = std::move(src_[name]->get_value(name, in_data));
|
|
|
|
|
}
|
2023-09-08 09:42:40 +00:00
|
|
|
|
else
|
2023-10-31 06:51:14 +00:00
|
|
|
|
value = device_option::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
if (size)
|
|
|
|
|
{
|
|
|
|
|
int n = 0;
|
|
|
|
|
child->get_value("size", n);
|
|
|
|
|
*size = n;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|
2023-09-15 09:53:13 +00:00
|
|
|
|
std::string device_option::get_option_field_string(const char* name, const char* key)
|
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
|
|
|
|
|
|
|
|
|
if (jsn)
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = nullptr;
|
|
|
|
|
|
|
|
|
|
jsn->get_value(name, child);
|
|
|
|
|
if (child)
|
|
|
|
|
{
|
|
|
|
|
child->get_value(key, value);
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|
|
|
|
|
std::string device_option::get_option_value_type(int sane_ind)
|
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
|
|
|
|
gb_json* jsn = now_ ? now_ : origin_;
|
|
|
|
|
|
|
|
|
|
if (sane_ind > 0 && sane_ind - 1 < jsn->children())
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = now_->child(sane_ind - 1);
|
|
|
|
|
child->get_value("type", value);
|
|
|
|
|
child->release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|
2023-10-31 06:51:14 +00:00
|
|
|
|
std::string device_option::get_option_value(int sane_ind, int type, int* size, void* in_data)
|
2023-09-15 09:53:13 +00:00
|
|
|
|
{
|
|
|
|
|
std::string value("");
|
|
|
|
|
|
|
|
|
|
if (now_)
|
|
|
|
|
{
|
|
|
|
|
if (sane_ind <= 0)
|
|
|
|
|
{
|
2023-10-31 06:51:14 +00:00
|
|
|
|
value = std::move(now_->to_string());
|
2023-09-15 09:53:13 +00:00
|
|
|
|
}
|
|
|
|
|
else if(sane_ind - 1 < now_->children())
|
|
|
|
|
{
|
|
|
|
|
gb_json* child = now_->child(sane_ind - 1);
|
2023-10-31 06:51:14 +00:00
|
|
|
|
std::string name(child->key());
|
2023-09-15 09:53:13 +00:00
|
|
|
|
|
|
|
|
|
child->release();
|
2023-10-31 06:51:14 +00:00
|
|
|
|
value = std::move(get_option_value(name.c_str(), type, size, in_data));
|
2023-09-15 09:53:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::move(value);
|
|
|
|
|
}
|