374 lines
7.6 KiB
C++
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)
|
|
{}
|