修改JSON以兼容APP配置
This commit is contained in:
parent
93ad04eb6a
commit
6c350e3b05
562
sane/gb_json.cpp
562
sane/gb_json.cpp
|
@ -30,6 +30,29 @@ namespace gb
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
static int load_mini_file(const char* file, std::string& cont)
|
||||||
|
{
|
||||||
|
FILE* src = fopen(file, "rb");
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
|
fseek(src, 0, SEEK_END);
|
||||||
|
size = ftell(src);
|
||||||
|
fseek(src, 0, SEEK_SET);
|
||||||
|
buf = new char[size + 4];
|
||||||
|
memset(buf, 0, size + 4);
|
||||||
|
fread(buf, 1, size, src);
|
||||||
|
fclose(src);
|
||||||
|
cont = std::string(buf, size);
|
||||||
|
delete[] buf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
refer::refer() : ref_(1)
|
refer::refer() : ref_(1)
|
||||||
{}
|
{}
|
||||||
|
@ -856,19 +879,209 @@ namespace gb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace updater
|
||||||
|
{
|
||||||
|
static std::string hg_model_from_pid(const char* pid)
|
||||||
|
{
|
||||||
|
if (strcmp(pid, "7823") == 0)
|
||||||
|
return "G200";
|
||||||
|
|
||||||
|
char m[] = { 'G', pid[0], '0', '0', 0};
|
||||||
|
|
||||||
|
return std::string(m) + " - " + pid;
|
||||||
|
}
|
||||||
|
static std::string hv_model_from_pid(const char* pid)
|
||||||
|
{
|
||||||
|
std::string m("");
|
||||||
|
if (strcmp(pid, "1000") == 0)
|
||||||
|
m = "HW-1000NS";
|
||||||
|
else if (strcmp(pid, "1002") == 0)
|
||||||
|
m = "HW-1000";
|
||||||
|
else if (strcmp(pid, "7000") == 0)
|
||||||
|
m = "HW-7000NS";
|
||||||
|
else if (strcmp(pid, "7002") == 0)
|
||||||
|
m = "HW-7000";
|
||||||
|
else if (strcmp(pid, "7039") == 0)
|
||||||
|
m = "HW-7000NS";
|
||||||
|
else
|
||||||
|
m = std::string("HW-") + pid;
|
||||||
|
|
||||||
|
return m + " - " + pid;
|
||||||
|
}
|
||||||
|
static std::string lsc_model_from_pid(const char* pid)
|
||||||
|
{
|
||||||
|
if (strcmp(pid, "8200") == 0)
|
||||||
|
return "G42S - 8200";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char m[] = {'G', pid[1], pid[2], 'S', 0};
|
||||||
|
|
||||||
|
return std::string(m) + " - " + pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static std::string scanner_chinese_name_2_model(const char* cn)
|
||||||
|
{
|
||||||
|
static const char* hg = "\345\215\216\351\253\230",
|
||||||
|
* hw = "\346\261\211\347\216\213",
|
||||||
|
* lsc = "\347\253\213\346\200\235\350\276\260",
|
||||||
|
* smy = "\346\211\253\346\217\217\344\273\252\342\200\224G",
|
||||||
|
* f = strstr(cn, hg);
|
||||||
|
std::string model("");
|
||||||
|
std::string(* model_from_pid)(const char* pid) = nullptr;
|
||||||
|
|
||||||
|
if (f == cn)
|
||||||
|
{
|
||||||
|
model = "HUAGOSCAN ";
|
||||||
|
model_from_pid = hg_model_from_pid;;
|
||||||
|
}
|
||||||
|
else if (strstr(cn, hw) == cn)
|
||||||
|
{
|
||||||
|
model = "Hanvon ";
|
||||||
|
model_from_pid = hv_model_from_pid;;
|
||||||
|
}
|
||||||
|
else if (strstr(cn, lsc) == cn)
|
||||||
|
{
|
||||||
|
model = "LANXUMSCAN ";
|
||||||
|
model_from_pid = lsc_model_from_pid;;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
|
||||||
|
f = strstr(cn, smy);
|
||||||
|
if (!f)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
f += strlen(smy);
|
||||||
|
model += model_from_pid(f);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
static int update_app_config(const char* scanner_name, const char* jsn_txt, const char* path, gb::scanner_cfg::LPUDF lpfunc)
|
||||||
|
{
|
||||||
|
std::string scanner(""), jsn_str(jsn_txt);
|
||||||
|
std::vector<std::string> efiles;
|
||||||
|
|
||||||
|
if ((unsigned char)scanner_name[0] > 0x7f)
|
||||||
|
scanner = scanner_chinese_name_2_model(scanner_name);
|
||||||
|
else
|
||||||
|
scanner = scanner_name;
|
||||||
|
|
||||||
|
gb::json* jsn = new gb::json();
|
||||||
|
int cur_sel = -1, ret = 0;
|
||||||
|
gb::scanner_cfg* cfg = nullptr;
|
||||||
|
if (!jsn->attach_text(&jsn_str[0]))
|
||||||
|
{
|
||||||
|
jsn->release();
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsn->first_child(jsn_str))
|
||||||
|
{
|
||||||
|
gb::json* child = new gb::json();
|
||||||
|
if (child->attach_text(&jsn_str[0]))
|
||||||
|
{
|
||||||
|
if (!child->get_value("cur_sel", cur_sel))
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
cfg = new gb::scanner_cfg();
|
||||||
|
int ind = 0;
|
||||||
|
while (jsn->next_child(jsn_str))
|
||||||
|
{
|
||||||
|
if (!child->attach_text(&jsn_str[0]))
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string schm_name("");
|
||||||
|
if (!child->get_value("scheme", schm_name))
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gb::json* items = nullptr;
|
||||||
|
if (!child->get_value("opts", items) || !items)
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gb::sane_config_schm* schm = new gb::sane_config_schm();
|
||||||
|
if (items->first_child(jsn_str))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::string name(""), val("");
|
||||||
|
gb::json* item = new gb::json();
|
||||||
|
if (item->attach_text(&jsn_str[0]))
|
||||||
|
{
|
||||||
|
if (item->get_value("name", name) && item->get_value("value", val))
|
||||||
|
{
|
||||||
|
name = lpfunc->title2name(name.c_str(), lpfunc->func_param);
|
||||||
|
lpfunc->trans_number(name.c_str(), val, lpfunc->func_param);
|
||||||
|
schm->set_value(name.c_str(), val.c_str(), val.length());
|
||||||
|
|
||||||
|
val = "";
|
||||||
|
item->get_value("extra", val);
|
||||||
|
if (val.length() && gb::load_mini_file(val.c_str(), val) == 0)
|
||||||
|
{
|
||||||
|
schm->set_value(name.c_str(), val.c_str(), val.length(), true);
|
||||||
|
item->get_value("extra", val);
|
||||||
|
efiles.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item->release();
|
||||||
|
} while (items->next_child(jsn_str));
|
||||||
|
}
|
||||||
|
items->release();
|
||||||
|
|
||||||
|
cfg->add_scheme(schm, schm_name.c_str());
|
||||||
|
schm->release();
|
||||||
|
if (ind++ == cur_sel)
|
||||||
|
cfg->select_scheme(schm_name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child->release();
|
||||||
|
}
|
||||||
|
jsn->release();
|
||||||
|
if (cfg)
|
||||||
|
{
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
cfg->save((path + scanner + ".cfg").c_str());
|
||||||
|
for (auto& v : efiles)
|
||||||
|
rename(v.c_str(), (v + "_bk").c_str());
|
||||||
|
}
|
||||||
|
cfg->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
namespace gb
|
namespace gb
|
||||||
{
|
{
|
||||||
std::string sane_config_schm::opt_data_appendix_("_data");
|
std::string sane_config_schm::opt_data_appendix_("_data");
|
||||||
|
|
||||||
sane_config_schm::sane_config_schm() : jsn_(NULL), bkp_(NULL), in_setting_(false), scheme_name_("")
|
sane_config_schm::sane_config_schm(scanner_cfg* scanner) : jsn_(NULL), bkp_(NULL), in_setting_(false), scheme_name_("")
|
||||||
|
, scanner_(scanner)
|
||||||
{
|
{
|
||||||
|
char empty[8] = { "{}" };
|
||||||
|
jsn_ = new gb::json();
|
||||||
|
jsn_->attach_text(empty);
|
||||||
def_val_ = new gb::json();
|
def_val_ = new gb::json();
|
||||||
|
if (scanner_)
|
||||||
|
scanner_->add_ref();
|
||||||
}
|
}
|
||||||
sane_config_schm::~sane_config_schm()
|
sane_config_schm::~sane_config_schm()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
def_val_->release();
|
def_val_->release();
|
||||||
|
if (scanner_)
|
||||||
|
scanner_->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sane_config_schm::hex(unsigned char ch, unsigned char* val)
|
bool sane_config_schm::hex(unsigned char ch, unsigned char* val)
|
||||||
|
@ -936,7 +1149,7 @@ namespace gb
|
||||||
if (bkp_)
|
if (bkp_)
|
||||||
bkp_->release();
|
bkp_->release();
|
||||||
bkp_ = NULL;
|
bkp_ = NULL;
|
||||||
file_ = L"";
|
// file_ = "";
|
||||||
}
|
}
|
||||||
std::string sane_config_schm::to_hex_letter(const char* data, size_t bytes)
|
std::string sane_config_schm::to_hex_letter(const char* data, size_t bytes)
|
||||||
{
|
{
|
||||||
|
@ -977,36 +1190,22 @@ namespace gb
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sane_config_schm::load_from_file(const wchar_t* file)
|
bool sane_config_schm::load_from_file(const char* file)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
bool ret = false;
|
std::string cont("");
|
||||||
FILE* src = _wfopen(file, L"rb");
|
|
||||||
if (src)
|
|
||||||
{
|
|
||||||
size_t size = 0;
|
|
||||||
char* buf = NULL;
|
|
||||||
gb::base64 b64;
|
|
||||||
|
|
||||||
fseek(src, 0, SEEK_END);
|
|
||||||
size = ftell(src);
|
|
||||||
fseek(src, 0, SEEK_SET);
|
|
||||||
buf = new char[size + 4];
|
|
||||||
memset(buf, 0, size + 4);
|
|
||||||
fread(buf, 1, size, src);
|
|
||||||
fclose(src);
|
|
||||||
ret = load_from_mem(buf);
|
|
||||||
delete[] buf;
|
|
||||||
}
|
|
||||||
file_ = file;
|
file_ = file;
|
||||||
|
if (gb::load_mini_file(file, cont))
|
||||||
|
return false;
|
||||||
|
|
||||||
return ret;
|
return load_from_mem(cont.c_str());
|
||||||
}
|
}
|
||||||
bool sane_config_schm::load_from_mem(const char* mem)
|
bool sane_config_schm::load_from_mem(const char* mem, bool in_b64)
|
||||||
{
|
{
|
||||||
gb::base64 b64;
|
gb::base64 b64;
|
||||||
std::string stream(b64.decode(mem, lstrlenA(mem)));
|
std::string stream(in_b64 ? b64.decode(mem, lstrlenA(mem)) : mem);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
jsn_ = new gb::json();
|
jsn_ = new gb::json();
|
||||||
|
@ -1020,7 +1219,7 @@ namespace gb
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool sane_config_schm::save_to(const wchar_t* file)
|
bool sane_config_schm::save_to(const char* file)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
std::string encode(to_text_stream());
|
std::string encode(to_text_stream());
|
||||||
|
@ -1030,7 +1229,7 @@ namespace gb
|
||||||
|
|
||||||
if (encode.length())
|
if (encode.length())
|
||||||
{
|
{
|
||||||
FILE* dst = _wfopen(file, L"wb");
|
FILE* dst = fopen(file, "wb");
|
||||||
|
|
||||||
if (dst)
|
if (dst)
|
||||||
{
|
{
|
||||||
|
@ -1091,13 +1290,7 @@ namespace gb
|
||||||
}
|
}
|
||||||
void sane_config_schm::config_changed(const char* name, const char* val, size_t bytes, bool extra)
|
void sane_config_schm::config_changed(const char* name, const char* val, size_t bytes, bool extra)
|
||||||
{
|
{
|
||||||
std::string hex_v(to_hex_letter(val, bytes)),
|
std::string hex_v(to_hex_letter(val, bytes));
|
||||||
def(default_value(name));
|
|
||||||
|
|
||||||
if (hex_v == def)
|
|
||||||
jsn_->remove(name);
|
|
||||||
else
|
|
||||||
jsn_->set_value(name, hex_v.c_str());
|
|
||||||
|
|
||||||
if (extra)
|
if (extra)
|
||||||
{
|
{
|
||||||
|
@ -1105,7 +1298,7 @@ namespace gb
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
def = default_value(name);
|
std::string def = default_value(name);
|
||||||
if (hex_v == def)
|
if (hex_v == def)
|
||||||
{
|
{
|
||||||
jsn_->remove(name);
|
jsn_->remove(name);
|
||||||
|
@ -1130,6 +1323,15 @@ namespace gb
|
||||||
if (jsn_)
|
if (jsn_)
|
||||||
jsn_->remove(name);
|
jsn_->remove(name);
|
||||||
}
|
}
|
||||||
|
void sane_config_schm::set_value(const char* name, const char* val, size_t bytes, bool extra)
|
||||||
|
{
|
||||||
|
std::string hex_v(to_hex_letter(val, bytes));
|
||||||
|
|
||||||
|
if (extra)
|
||||||
|
jsn_->set_value((name + sane_config_schm::opt_data_appendix_).c_str(), hex_v.c_str());
|
||||||
|
else
|
||||||
|
jsn_->set_value(name, hex_v.c_str());
|
||||||
|
}
|
||||||
void sane_config_schm::end_setting(bool cancel)
|
void sane_config_schm::end_setting(bool cancel)
|
||||||
{
|
{
|
||||||
if (in_setting_)
|
if (in_setting_)
|
||||||
|
@ -1158,22 +1360,26 @@ namespace gb
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::string sane_config_schm::to_text_stream(void)
|
std::string sane_config_schm::to_text_stream(bool b64, bool with_ver)
|
||||||
{
|
{
|
||||||
if (jsn_)
|
if (jsn_)
|
||||||
{
|
{
|
||||||
|
if(with_ver)
|
||||||
{
|
{
|
||||||
char ver[40] = { 0 };
|
char ver[40] = { 0 };
|
||||||
sprintf_s(ver, "%u.%u", VERSION_MAIN, VERSION_SUB);
|
sprintf_s(ver, "%u.%u", VERSION_MAIN, VERSION_SUB);
|
||||||
jsn_->set_value("ver", ver);
|
jsn_->set_value("ver", ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cont(jsn_->to_string(false)), encode("");
|
std::string cont(jsn_->to_string(false));
|
||||||
gb::base64 b64;
|
if (b64)
|
||||||
|
{
|
||||||
|
gb::base64 b64;
|
||||||
|
|
||||||
encode = b64.encode(cont.c_str(), cont.length());
|
cont = b64.encode(cont.c_str(), cont.length());
|
||||||
|
}
|
||||||
|
|
||||||
return encode;
|
return cont;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
|
@ -1254,4 +1460,284 @@ namespace gb
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// scanner_cfg
|
// scanner_cfg
|
||||||
|
std::string scanner_cfg::global_name_ = "global";
|
||||||
|
std::string scanner_cfg::cur_sel_ = "cur";
|
||||||
|
std::string scanner_cfg::default_setting_name_ = "\351\273\230\350\256\244\350\256\276\347\275\256"; // utf-8: 默认设置
|
||||||
|
|
||||||
|
scanner_cfg::scanner_cfg() : path_(""), scanner_name_(""), global_(new json())
|
||||||
|
{
|
||||||
|
init_version();
|
||||||
|
init_select();
|
||||||
|
}
|
||||||
|
scanner_cfg::~scanner_cfg()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
global_->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scanner_cfg::update(const char* file, LPUDF func)
|
||||||
|
{
|
||||||
|
std::string cont(""), name(""), path(file);
|
||||||
|
int ret = gb::load_mini_file(file, cont);
|
||||||
|
base64 b64;
|
||||||
|
json *jsn = nullptr;
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return false;
|
||||||
|
else if (cont.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
cont = b64.decode(cont.c_str(), cont.length());
|
||||||
|
jsn = new json();
|
||||||
|
if (!jsn->attach_text(&cont[0]))
|
||||||
|
{
|
||||||
|
jsn->release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cont = "";
|
||||||
|
ret = path.rfind(PATH_SYMBOL[0]);
|
||||||
|
if (ret++ != std::string::npos)
|
||||||
|
path.erase(ret);
|
||||||
|
if (jsn->first_child(cont, &name))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ok &= updater::update_app_config(name.c_str(), cont.c_str(), path.c_str(), func) == 0;
|
||||||
|
} while (jsn->next_child(cont, &name));
|
||||||
|
}
|
||||||
|
jsn->release();
|
||||||
|
if (ok)
|
||||||
|
rename(file, (std::string(file) + "_bk").c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanner_cfg::clear(void)
|
||||||
|
{
|
||||||
|
global_->set_value("ver", "");
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), -1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < schemes_.size(); ++i)
|
||||||
|
schemes_[i].schm->release();
|
||||||
|
schemes_.clear();
|
||||||
|
scanner_name_ = "";
|
||||||
|
}
|
||||||
|
void scanner_cfg::init_version(void)
|
||||||
|
{
|
||||||
|
char vstr[40] = { 0 };
|
||||||
|
|
||||||
|
sprintf(vstr, "%u.%u", VERSION_MAIN, VERSION_SUB);
|
||||||
|
global_->set_value("ver", vstr);
|
||||||
|
}
|
||||||
|
void scanner_cfg::init_select(void)
|
||||||
|
{
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), -1);
|
||||||
|
}
|
||||||
|
void scanner_cfg::walk_sibling_schemes(cJSON* first)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cJSON* next = first->next;
|
||||||
|
std::string name(first->string ? "" : first->string),
|
||||||
|
cont("");
|
||||||
|
CFGSCHM sch;
|
||||||
|
|
||||||
|
first->next = nullptr;
|
||||||
|
cont = json::to_string(first, false);
|
||||||
|
if (name == scanner_cfg::global_name_)
|
||||||
|
{
|
||||||
|
global_->attach_text(&cont[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sch.schm = new sane_config_schm();
|
||||||
|
if (sch.schm->load_from_mem(cont.c_str(), false))
|
||||||
|
{
|
||||||
|
sch.name = sane_config_schm::from_hex_letter(name.c_str(), name.length());
|
||||||
|
sch.schm->set_scheme_name(sch.name.c_str());
|
||||||
|
schemes_.push_back(sch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sch.schm->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
first->next = next;
|
||||||
|
walk_sibling_schemes(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
int scanner_cfg::load_file(const char* file)
|
||||||
|
{
|
||||||
|
std::string cont("");
|
||||||
|
int ret = gb::load_mini_file(file, cont);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = load_mem(cont.c_str());
|
||||||
|
|
||||||
|
if (ret == 0 && scanner_name_.empty())
|
||||||
|
{
|
||||||
|
const char* name = strrchr(file, PATH_SYMBOL[0]);
|
||||||
|
if (name++ == nullptr)
|
||||||
|
name = file;
|
||||||
|
|
||||||
|
scanner_name_ = name;
|
||||||
|
ret = scanner_name_.rfind('.');
|
||||||
|
if (ret != std::string::npos)
|
||||||
|
scanner_name_.erase(ret);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int scanner_cfg::load_mem(const char* mem)
|
||||||
|
{
|
||||||
|
cJSON* root = cJSON_Parse(mem);
|
||||||
|
|
||||||
|
if (!root)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
clear();
|
||||||
|
walk_sibling_schemes(root->child);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int scanner_cfg::save(const char* file)
|
||||||
|
{
|
||||||
|
if (!file && path_.empty() && scanner_name_.empty())
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
std::string cont("{\"" + scanner_cfg::global_name_ + "\":"),
|
||||||
|
f(file ? file : path_ + scanner_name_),
|
||||||
|
v("");
|
||||||
|
int sel = -1;
|
||||||
|
|
||||||
|
if (!global_->get_value("ver", v) || v.empty())
|
||||||
|
init_version();
|
||||||
|
if (!global_->get_value(scanner_cfg::cur_sel_.c_str(), sel) || sel >= schemes_.size())
|
||||||
|
init_select();
|
||||||
|
|
||||||
|
cont += global_->to_string(false);
|
||||||
|
for (auto& v: schemes_)
|
||||||
|
{
|
||||||
|
cont += ",\"" + sane_config_schm::to_hex_letter(v.name.c_str(), v.name.length()) + "\":";
|
||||||
|
cont += v.schm->to_text_stream(false, false);
|
||||||
|
}
|
||||||
|
cont += "}";
|
||||||
|
|
||||||
|
base64 b64;
|
||||||
|
FILE* dst = fopen(f.c_str(), "wb");
|
||||||
|
|
||||||
|
if (!dst)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
f = b64.encode(cont.c_str(), cont.length());
|
||||||
|
fwrite(f.c_str(), 1, f.length(), dst);
|
||||||
|
fclose(dst);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanner_cfg::get_all_schemes(std::vector<std::string>& schemes)
|
||||||
|
{
|
||||||
|
schemes.push_back(scanner_cfg::default_setting_name_);
|
||||||
|
for (auto& v : schemes_)
|
||||||
|
schemes.push_back(v.name);
|
||||||
|
}
|
||||||
|
sane_config_schm* scanner_cfg::get_scheme(const char* scheme_name)
|
||||||
|
{
|
||||||
|
sane_config_schm* found = nullptr;
|
||||||
|
|
||||||
|
if (scheme_name)
|
||||||
|
{
|
||||||
|
std::vector<CFGSCHM>::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name);
|
||||||
|
if (it != schemes_.end())
|
||||||
|
found = it->schm;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ind = -1;
|
||||||
|
|
||||||
|
global_->get_value(scanner_cfg::cur_sel_.c_str(), ind);
|
||||||
|
if (ind >= 0 && ind < schemes_.size())
|
||||||
|
found = schemes_[ind].schm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
found->add_ref();
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
bool scanner_cfg::remove_scheme(const char* scheme_name)
|
||||||
|
{
|
||||||
|
std::vector<CFGSCHM>::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name);
|
||||||
|
|
||||||
|
if (it != schemes_.end())
|
||||||
|
{
|
||||||
|
int id = it - schemes_.begin(),
|
||||||
|
ind = -1;
|
||||||
|
|
||||||
|
it->schm->release();
|
||||||
|
schemes_.erase(it);
|
||||||
|
global_->get_value(scanner_cfg::cur_sel_.c_str(), ind);
|
||||||
|
if (ind == id)
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), -1);
|
||||||
|
else if (ind > id)
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), ind - 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool scanner_cfg::select_scheme(const char* scheme_name)
|
||||||
|
{
|
||||||
|
std::vector<CFGSCHM>::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name);
|
||||||
|
|
||||||
|
if (it == schemes_.end())
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), -1);
|
||||||
|
else
|
||||||
|
global_->set_value(scanner_cfg::cur_sel_.c_str(), it - schemes_.begin());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sane_config_schm* scanner_cfg::copy_scheme(const char* cp_from_name) // for UI setting, call release() if not use anymore
|
||||||
|
{
|
||||||
|
if (!cp_from_name)
|
||||||
|
return nullptr;
|
||||||
|
else if (scanner_cfg::default_setting_name_ == cp_from_name)
|
||||||
|
return new sane_config_schm();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<CFGSCHM>::iterator it = std::find(schemes_.begin(), schemes_.end(), cp_from_name);
|
||||||
|
if (it == schemes_.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::string cont(it->schm->to_text_stream());
|
||||||
|
sane_config_schm* schm = new sane_config_schm();
|
||||||
|
schm->load_from_mem(cont.c_str());
|
||||||
|
|
||||||
|
return schm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool scanner_cfg::add_scheme(sane_config_schm* schm, const char* name)
|
||||||
|
{
|
||||||
|
if (name && std::find(schemes_.begin(), schemes_.end(), name) != schemes_.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CFGSCHM cs;
|
||||||
|
cs.name = name ? name : schm->get_scheme_name();
|
||||||
|
cs.schm = schm;
|
||||||
|
if (cs.name == scanner_cfg::global_name_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
schemes_.push_back(cs);
|
||||||
|
schm->set_scheme_name(cs.name.c_str());
|
||||||
|
schm->add_ref();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if defined(WIN32) || defined(_WIN64)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#define PATH_SYMBOL "\\"
|
||||||
|
#else
|
||||||
|
#define PATH_SYMBOL "/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #include "cJSON.h"
|
// #include "cJSON.h"
|
||||||
|
@ -12,6 +15,7 @@
|
||||||
|
|
||||||
namespace gb
|
namespace gb
|
||||||
{
|
{
|
||||||
|
class scanner_cfg;
|
||||||
class refer
|
class refer
|
||||||
{
|
{
|
||||||
volatile long ref_;
|
volatile long ref_;
|
||||||
|
@ -101,7 +105,8 @@ namespace gb
|
||||||
class sane_config_schm : public refer
|
class sane_config_schm : public refer
|
||||||
{
|
{
|
||||||
std::string scheme_name_;
|
std::string scheme_name_;
|
||||||
std::wstring file_;
|
scanner_cfg *scanner_;
|
||||||
|
std::string file_;
|
||||||
json* jsn_;
|
json* jsn_;
|
||||||
json* bkp_;
|
json* bkp_;
|
||||||
json* def_val_;
|
json* def_val_;
|
||||||
|
@ -109,25 +114,25 @@ namespace gb
|
||||||
std::map<int, std::string> id_name_; // (id, default-val)
|
std::map<int, std::string> id_name_; // (id, default-val)
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
std::string to_hex_letter(const char* data, size_t bytes);
|
|
||||||
std::string from_hex_letter(const char* data, size_t bytes);
|
|
||||||
std::string default_value(const char* name);
|
std::string default_value(const char* name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~sane_config_schm();
|
~sane_config_schm();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sane_config_schm();
|
sane_config_schm(scanner_cfg* scanner = nullptr);
|
||||||
|
|
||||||
static std::string opt_data_appendix_;
|
static std::string opt_data_appendix_;
|
||||||
static bool hex(unsigned char ch, unsigned char* val);
|
static bool hex(unsigned char ch, unsigned char* val);
|
||||||
static bool hex_char(const char* data, unsigned char* val);
|
static bool hex_char(const char* data, unsigned char* val);
|
||||||
|
static std::string to_hex_letter(const char* data, size_t bytes);
|
||||||
|
static std::string from_hex_letter(const char* data, size_t bytes);
|
||||||
static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true
|
static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool load_from_file(const wchar_t* file);
|
bool load_from_file(const char* file);
|
||||||
bool load_from_mem(const char* mem);
|
bool load_from_mem(const char* mem, bool in_b64 = true);
|
||||||
bool save_to(const wchar_t* file);
|
bool save_to(const char* file);
|
||||||
void set_default_value(int sn, const char* name, const char* val, size_t bytes);
|
void set_default_value(int sn, const char* name, const char* val, size_t bytes);
|
||||||
bool first_config(std::string& name, std::string& val);
|
bool first_config(std::string& name, std::string& val);
|
||||||
bool next_config(std::string& name, std::string& val);
|
bool next_config(std::string& name, std::string& val);
|
||||||
|
@ -135,12 +140,82 @@ namespace gb
|
||||||
void config_changed(const char* name, const char* val, size_t bytes, bool extra = false);
|
void config_changed(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||||
void config_changed(int sn, const char* val, size_t bytes, bool extra = false);
|
void config_changed(int sn, const char* val, size_t bytes, bool extra = false);
|
||||||
void remove_config(const char* name);
|
void remove_config(const char* name);
|
||||||
|
void set_value(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||||
void end_setting(bool cancel);
|
void end_setting(bool cancel);
|
||||||
int id_from_name(const char* name);
|
int id_from_name(const char* name);
|
||||||
std::string to_text_stream(void);
|
std::string to_text_stream(bool b64 = true, bool with_ver = true);
|
||||||
std::string get_version(void);
|
std::string get_version(void);
|
||||||
std::string get_scheme_name(void);
|
std::string get_scheme_name(void);
|
||||||
void set_scheme_name(const char* name);
|
void set_scheme_name(const char* name);
|
||||||
void update(bool(__stdcall* is_float)(int, void*), void* param, const char*(__stdcall* t2n)(const char*), std::string* discard = NULL);
|
void update(bool(__stdcall* is_float)(int, void*), void* param, const char*(__stdcall* t2n)(const char*), std::string* discard = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class scanner_cfg : public refer
|
||||||
|
{
|
||||||
|
// format: in base64
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// "global": {
|
||||||
|
// "ver": "4.33",
|
||||||
|
// "cur": -1
|
||||||
|
// },
|
||||||
|
// "scheme_1": sane_config_schm*,
|
||||||
|
// "scheme_2": sane_config_schm*,
|
||||||
|
// "scheme_3": sane_config_schm*,
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
std::string path_;
|
||||||
|
std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100
|
||||||
|
json *global_; // version, current scheme, ...
|
||||||
|
|
||||||
|
typedef struct _cfg_schm
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
sane_config_schm* schm;
|
||||||
|
|
||||||
|
bool operator==(const char* n)
|
||||||
|
{
|
||||||
|
return name == n;
|
||||||
|
}
|
||||||
|
}CFGSCHM;
|
||||||
|
std::vector<CFGSCHM> schemes_;
|
||||||
|
|
||||||
|
static std::string global_name_;
|
||||||
|
static std::string cur_sel_;
|
||||||
|
static std::string default_setting_name_;
|
||||||
|
|
||||||
|
void clear(void);
|
||||||
|
void init_version(void);
|
||||||
|
void init_select(void);
|
||||||
|
void walk_sibling_schemes(cJSON* first);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~scanner_cfg();
|
||||||
|
|
||||||
|
public:
|
||||||
|
scanner_cfg();
|
||||||
|
|
||||||
|
typedef struct _update_func
|
||||||
|
{
|
||||||
|
void(__stdcall* trans_number)(const char* name, std::string& val, void* param);
|
||||||
|
const char* (__stdcall* title2name)(const char* title, void* param);
|
||||||
|
std::string discard_msg; // update failed items ...
|
||||||
|
void* func_param;
|
||||||
|
}UDF, *LPUDF;
|
||||||
|
static bool update(const char* file, LPUDF func);
|
||||||
|
|
||||||
|
public:
|
||||||
|
int load_file(const char* file);
|
||||||
|
int load_mem(const char* mem);
|
||||||
|
int save(const char* file = nullptr);
|
||||||
|
|
||||||
|
void get_all_schemes(std::vector<std::string>& schemes); // return all schemes name queue, the first is always be 'Default settings'
|
||||||
|
sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore
|
||||||
|
bool remove_scheme(const char* scheme_name);
|
||||||
|
bool select_scheme(const char* scheme_name);
|
||||||
|
|
||||||
|
sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore
|
||||||
|
bool add_scheme(sane_config_schm* schm, const char* name = nullptr);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -559,12 +559,12 @@ void scanner::update_config(void)
|
||||||
}
|
}
|
||||||
void scanner::load_config(const wchar_t* file)
|
void scanner::load_config(const wchar_t* file)
|
||||||
{
|
{
|
||||||
cfg_->load_from_file(file);
|
cfg_->load_from_file(local_trans::u2a(file).c_str());
|
||||||
update_config();
|
update_config();
|
||||||
}
|
}
|
||||||
void scanner::save_config(const wchar_t* file)
|
void scanner::save_config(const wchar_t* file)
|
||||||
{
|
{
|
||||||
cfg_->save_to(file);
|
cfg_->save_to(local_trans::u2a(file).c_str());
|
||||||
}
|
}
|
||||||
void scanner::apply_config(void)
|
void scanner::apply_config(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue