newtx/sdk/sane_opt_json/base_opt.cpp

374 lines
7.6 KiB
C++

#include "base_opt.h"
#include <json/gb_json.h>
#include <huagao/hgscanner_error.h>
#include <sane/sane_ex.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
template<class T>
static void get_range_values(std::string& ret, gb_json* range, bool* isrange)
{
std::string values("");
T v;
if(range->get_value("min", v))
{
if(isrange)
*isrange = true;
ret += std::string((char*)&v, sizeof(v));
range->get_value("max", v);
ret += std::string((char*)&v, sizeof(v));
range->get_value("step", v);
ret += std::string((char*)&v, sizeof(v));
}
else
{
if(isrange)
*isrange = false;
gb_json* val = range->first_child();
while(val)
{
val->value(v);
ret += std::string((char*)&v, sizeof(v));
val->release();
val = range->next_child();
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
sane_opt_provider::sane_opt_provider()
{
set_where(nullptr);
}
sane_opt_provider::~sane_opt_provider()
{
for (auto& v : following_)
v.second->release();
following_.clear();
}
std::string sane_opt_provider::sane_value_2_readable_text(SANE_Value_Type type, void* value)
{
if(type == SANE_TYPE_BOOL)
return *(bool*)value ? "true" : "false";
else if(type == SANE_TYPE_INT)
return std::to_string(*(int*)value);
else if(type == SANE_TYPE_FIXED)
return std::to_string(*(double*)value);
else if(type == SANE_TYPE_STRING)
return (char*)value;
else
return "";
}
std::string sane_opt_provider::sane_value_2_readable_text(const char* type, void* value)
{
if(strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
return *(bool*)value ? "true" : "false";
else if(strcmp(type, JSON_SANE_TYPE_INT) == 0)
return std::to_string(*(int*)value);
else if(strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
return std::to_string(*(double*)value);
else if(strcmp(type, JSON_SANE_TYPE_STRING) == 0)
return (char*)value;
else
return "";
}
std::string sane_opt_provider::sane_value_from_readable_text(SANE_Value_Type type, const char* text)
{
std::string val("");
if(type == SANE_TYPE_BOOL)
{
bool v = strcmp(text, "true") == 0;
val = std::string((char*)&v, sizeof(v));
}
else if(type == SANE_TYPE_INT)
{
int v = atoi(text);
val = std::string((char*)&v, sizeof(v));
}
else if(type == SANE_TYPE_FIXED)
{
double v = atof(text);
val = std::string((char*)&v, sizeof(v));
}
else if(type == SANE_TYPE_STRING)
{
val = text;
}
return std::move(val);
}
std::string sane_opt_provider::sane_value_from_readable_text(const char* type, const char* text)
{
std::string val("");
if(strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
{
bool v = strcmp(text, "true") == 0;
val = std::string((char*)&v, sizeof(v));
}
else if(strcmp(type, JSON_SANE_TYPE_INT) == 0)
{
int v = atoi(text);
val = std::string((char*)&v, sizeof(v));
}
else if(strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
{
double v = atof(text);
val = std::string((char*)&v, sizeof(v));
}
else if(strcmp(type, JSON_SANE_TYPE_STRING) == 0)
{
val = text;
}
return std::move(val);
}
bool sane_opt_provider::set_opt_value(gb_json* opt, void* value, const char* key)
{
std::string type("");
bool ret = true;
opt->get_value("type", type);
if (!key || *key == 0)
key = "cur";
if (type == JSON_SANE_TYPE_BOOL)
{
opt->set_value(key, *(bool*)value);
}
else if (type == JSON_SANE_TYPE_INT)
{
opt->set_value(key, *(int*)value);
}
else if (type == JSON_SANE_TYPE_FIXED)
{
opt->set_value(key, *(double*)value);
}
else if (type == JSON_SANE_TYPE_STRING)
{
opt->set_value(key, (char*)value);
}
else
{
ret = false;
}
return ret;
}
bool sane_opt_provider::is_opt_value_equal(gb_json* opt, void* v1, void* v2)
{
std::string type("");
bool ret = true;
opt->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
{
ret = *(bool*)v1 == *(bool*)v2;
}
else if (type == JSON_SANE_TYPE_INT)
{
ret = *(int*)v1 == *(int*)v2;
}
else if (type == JSON_SANE_TYPE_FIXED)
{
ret = *(double*)v1 == *(double*)v2;
}
else if (type == JSON_SANE_TYPE_STRING)
{
ret = strcmp((char*)v1, (char*)v2) == 0;
}
return ret;
}
std::string sane_opt_provider::option_value(gb_json* jsn, bool def_val, SANE_Value_Type* type)
{
std::string vt(""), key(def_val ? "default" : "cur");
jsn->get_value("type", vt);
if (vt == "bool")
{
bool v = false;
jsn->get_value(key.c_str(), v);
vt = std::string((char*)&v, sizeof(v));
if(type)
*type = SANE_TYPE_BOOL;
}
else if (vt == "int")
{
int v = 0;
jsn->get_value(key.c_str(), v);
vt = std::string((char*)&v, sizeof(v));
if(type)
*type = SANE_TYPE_INT;
}
else if (vt == "float")
{
double v = .0f;
jsn->get_value(key.c_str(), v);
vt = std::string((char*)&v, sizeof(v));
if(type)
*type = SANE_TYPE_FIXED;
}
else if (vt == "string")
{
if (!jsn->get_value(key.c_str(), vt))
vt = "";
if(type)
*type = SANE_TYPE_STRING;
}
else
{
vt = "";
}
return std::move(vt);
}
std::string sane_opt_provider::get_all_values(gb_json* opt, SANE_Constraint_Type* constraint, SANE_Value_Type* type)
{
std::string vt(""), value("");
SANE_Value_Type t = SANE_TYPE_BOOL;
gb_json *range = nullptr, *child = nullptr;
if(!type)
type = &t;
value = sane_opt_provider::option_value(opt, false, type);
opt->get_value("range", range);
if(*type == SANE_TYPE_STRING)
{
value.append(3, '\0');
utils::add_2_string_array(value, sane_opt_provider::option_value(opt, true).c_str());
if(range)
{
if(constraint)
*constraint = SANE_CONSTRAINT_STRING_LIST;
child = range->first_child();
while(child)
{
child->value(vt);
utils::add_2_string_array(value, vt.c_str());
child->release();
child = range->next_child();
}
range->release();
}
}
else
{
value += sane_opt_provider::option_value(opt, true);
if(range)
{
bool isrng = false;
if(*type == SANE_TYPE_BOOL)
{
get_range_values<bool>(value, range, &isrng);
}
else if(*type == SANE_TYPE_INT)
{
get_range_values<int>(value, range, &isrng);
}
else if(*type == SANE_TYPE_FIXED)
{
get_range_values<double>(value, range, &isrng);
}
range->release();
if(constraint)
*constraint = isrng ? SANE_CONSTRAINT_RANGE : SANE_CONSTRAINT_WORD_LIST;
}
}
return std::move(value);
}
bool sane_opt_provider::set_opt_json_text(char* txt)
{
gb_json* jsn = new gb_json();
bool ret = jsn->attach_text(txt);
jsn->release();
if (ret)
opt_jsn_txt_ = txt;
else
opt_jsn_txt_ = "";
return ret;
}
void sane_opt_provider::set_where(const char* where)
{
if (where && *where)
{
where_ = where;
}
else
{
char buf[20] = { 0 };
sprintf(buf, "%p", this);
where_ = buf;
}
}
const char* sane_opt_provider::get_opt_json(void)
{
return opt_jsn_txt_.c_str();
}
const char* sane_opt_provider::from(void)
{
return where_.c_str();
}
void sane_opt_provider::set_following_provider(const char* name, sane_opt_provider* following)
{
if (following_.count(name))
{
following_[name]->release();
following_.erase(name);
}
if (following)
{
following_[name] = following;
following->add_ref();
}
}
sane_opt_provider* sane_opt_provider::get_following(const char* name)
{
sane_opt_provider* prvd = nullptr;
if (following_.count(name))
{
prvd = following_[name];
if (prvd)
prvd->add_ref();
}
return prvd;
}
char* sane_opt_provider::get_value(const char* name, void* value, size_t* size, int* err)
{
if (err)
*err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
if (size)
*size = 0;
return nullptr;
}
int sane_opt_provider::set_value(const char* name, void* val)
{
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
void sane_opt_provider::enable(const char* name, bool able)
{}