adjust sane files

This commit is contained in:
gb 2023-08-22 16:47:28 +08:00
parent a0123c49b9
commit c2e188d8c0
17 changed files with 1318 additions and 780 deletions

View File

@ -11,7 +11,7 @@ add_compile_options(-std=c++11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -O2")
aux_source_directory(${PROJECT_SOURCE_DIR} DIR_SRCS)
file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*.h" "${PROJECT_SOURCE_DIR}/*.hpp")
file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*.h" "${PROJECT_SOURCE_DIR}/*.hpp" "${PROJECT_SOURCE_DIR}/../*.h" "${PROJECT_SOURCE_DIR}/../*.c" "${PROJECT_SOURCE_DIR}/../*.cpp")
set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS})
add_library(${PROJECT_NAME} SHARED ${DIR_SRCS})
link_directories(${PROJECT_NAME} PRIVATE
@ -26,6 +26,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE hgdriver
target_link_libraries(${PROJECT_NAME} PRIVATE -static-libgcc -static-libstdc++ -Wl,--exclude-libs,ALL -zdefs -Bdirect pthread dl -Wl,-rpath,$ORIGIN)
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/../sdk/hginclude
${PROJECT_SOURCE_DIR}/../sdk/json
${PROJECT_SOURCE_DIR}/../../sdk/include
)

121
hgsane/entry.cpp Normal file
View File

@ -0,0 +1,121 @@
#include "sane_hg_mdw.h"
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h" // for log-api
#include "../sdk/hginclude/utils.h" // for log-level
/// <summary>
/// SANE API entrance ...
/// </summary>
extern "C" { // avoid compiler exporting name in C++ style !!!
const char* inner_sane_err_desc(SANE_Status err)
{
return hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err));
}
SANE_Status inner_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize)
{
hg_sane_middleware::set_app_callback((void*)authorize);
if (!hg_sane_middleware::instance()->is_ready())
return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST;
hg_sane_middleware::get_version(version_code);
return SANE_STATUS_GOOD;
}
void inner_sane_exit(void)
{
hg_sane_middleware::clear();
}
SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only)
{
SANE_Status code = hg_sane_middleware::instance()->get_devices(device_list, local_only);
return code;
}
SANE_Status inner_sane_open(SANE_String_Const devicename, SANE_Handle* handle)
{
return hg_sane_middleware::instance()->open_device(devicename, handle);
}
void inner_sane_close(SANE_Handle handle)
{
hg_sane_middleware::instance()->close_device(handle);
}
const SANE_Option_Descriptor*
inner_sane_get_option_descriptor(SANE_Handle handle, const void* option)
{
return hg_sane_middleware::instance()->get_option_descriptor(handle, option);
}
SANE_Status inner_sane_control_option(SANE_Handle handle, const void* option, SANE_Action action, void* value, SANE_Int* info)
{
return hg_sane_middleware::instance()->set_option(handle, option, action, value, info);
}
SANE_Status inner_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params)
{
return hg_sane_middleware::instance()->get_image_parameters(handle, params);
}
SANE_Status inner_sane_start(SANE_Handle handle)
{
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_start\n");
return hg_sane_middleware::instance()->start(handle, NULL);
}
SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length)
{
if (!length)
length = &max_length;
else
*length = max_length;
return hg_sane_middleware::instance()->read(handle, data, length);
}
void inner_sane_cancel(SANE_Handle handle)
{
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_cancel\n");
hg_sane_middleware::instance()->stop(handle);
}
SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
{
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_set_io_mode\n");
return non_blocking ? SANE_STATUS_UNSUPPORTED : SANE_STATUS_GOOD;
}
SANE_Status inner_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd)
{
return SANE_STATUS_UNSUPPORTED;
}
SANE_String_Const inner_sane_strstatus(SANE_Status status)
{
// return hg_scanner_err_name(status);
return inner_sane_err_desc(status);
}
void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap)
{
}
/// following are extensions for standard ...
SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param)
{
hg_sane_middleware::set_app_callback(cb, param, hg_sane_middleware::APP_CALLBACK_EX);
if (!hg_sane_middleware::instance()->is_ready())
return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST;
hg_sane_middleware::get_version(version_code);
return SANE_STATUS_GOOD;
}
SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len)
{
return hg_sane_middleware::instance()->io_control(h, code, data, len);
}
SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len)
{
return SANE_STATUS_UNSUPPORTED;
}
}

View File

@ -1,364 +0,0 @@
#include "json.h"
#include <stdlib.h>
#include <string.h>
#if defined(WIN32) || defined(_WIN64)
#define bzero(b, s) memset(b, 0, s)
#endif
json::json(char* json_txt) : obj_(0), cur_child_(0)
{
attach_text(json_txt);
}
json::~json()
{
clear();
}
std::string json::to_string(cJSON* root)
{
char* txt = cJSON_Print(root);
std::string ret(txt ? txt : "");
if (txt)
free(txt);
return ret;
}
std::string json::get_value_as_string(cJSON* root, bool integer)
{
std::string ret("");
switch (root->type)
{
case cJSON_False:
ret = "false";
break;
case cJSON_True:
ret = "true";
break;
case cJSON_NULL:
ret = "null";
break;
case cJSON_Number:
{
char buf[40];
if (integer)
sprintf(buf, "%d", root->valueint);
else
sprintf(buf, "%f", root->valuedouble);
ret = buf;
}
break;
case cJSON_String:
if (root->valuestring)
ret = root->valuestring;
break;
default:
ret = json::to_string(root);
break;
}
return ret;
}
cJSON* json::find_child(cJSON *parent, const char* child_name)
{
if (!parent)
return 0;
cJSON *child = parent->child;
while (child)
{
if (child->string && strcmp(child->string, child_name) == 0)
break;
child = child->next;
}
return child;
}
cJSON* json::find(const char* path)
{
cJSON *found = obj_;
if (path && *path)
{
std::string all(path);
char *cur = strtok(&all[0], "/");
while (cur)
{
found = find_child(found, cur);
if (!found)
break;
cur = strtok(0, "/");
}
}
return found;
}
bool json::attach_text(char* json_txt)
{
clear();
obj_ = cJSON_Parse(json_txt);
return obj_ != 0;
}
bool json::attach_cjson(cJSON* cjson)
{
clear();
if (cjson)
{
std::string txt(json::to_string(cjson));
if (txt.length())
obj_ = cJSON_Parse(txt.c_str());
}
return obj_ != 0;
}
void json::clear(void)
{
if (obj_)
{
cJSON_Delete(obj_);
obj_ = 0;
}
}
std::string json::to_string(void)
{
if (obj_)
return json::to_string(obj_);
else
return "";
}
std::string json::key(void)
{
if (obj_ && obj_->string)
return obj_->string;
else
return "";
}
bool json::get_value(const char* key, bool& val)
{
cJSON* obj = find(key);
if (!obj)
return false;
if (obj->type == cJSON_True)
val = true;
else if (obj->type == cJSON_False)
val = false;
else
return false;
return true;
}
bool json::get_value(const char* key, int& val)
{
cJSON* obj = find(key);
if (!obj)
return false;
if (obj->type != cJSON_Number)
return false;
val = obj->valueint;
return true;
}
bool json::get_value(const char* key, double& val)
{
cJSON *obj = find(key);
if (!obj)
return false;
if (obj->type != cJSON_Number)
return false;
val = obj->valuedouble;
return true;
}
bool json::get_value(const char* key, std::string& val)
{
cJSON *obj = find(key);
if (!obj)
return false;
if (obj->type != cJSON_String)
return false;
val = obj->valuestring ? obj->valuestring : "";
return true;
}
bool json::get_value(const char* key, json*& val)
{
cJSON *obj = find(key);
if (!obj)
return false;
val = new json();
if (!val->attach_cjson(obj))
{
delete val;
return false;
}
return true;
}
bool json::get_value_as_string(const char* key, std::string& val, bool integer)
{
cJSON* obj = find(key);
if (!obj)
return false;
val = json::get_value_as_string(obj, integer);
return true;
}
bool json::get_as_array(const char* key, std::vector<std::string>& val)
{
cJSON *obj = find(key);
val.clear();
if (obj && obj->type == cJSON_Array)
{
cJSON *child = obj->child;
while (child)
{
if (child->type == cJSON_Number)
{
char buf[40];
sprintf(buf, "%d", child->valueint);
val.push_back(buf);
}
else if (child->type == cJSON_String)
val.push_back(child->valuestring ? child->valuestring : "");
else
{
char *text = cJSON_Print(child);
val.push_back(text);
free(text);
}
child = child->next;
}
return true;
}
return false;
}
bool json::first_child(std::string& val)
{
cur_child_ = obj_->child;
val = "";
if (cur_child_)
{
val = json::get_value_as_string(cur_child_);
return true;
}
else
{
return false;
}
}
bool json::next_child(std::string& val)
{
if (cur_child_)
cur_child_ = cur_child_->next;
val = "";
if (cur_child_)
{
val = json::get_value_as_string(cur_child_);
return true;
}
else
{
return false;
}
}
bool json::set_value(const char* key, bool val)
{
cJSON* ele = this->find(key);
if (!ele)
return false;
if (ele->type == cJSON_String)
free(ele->valuestring);
if (val)
ele->type = cJSON_True;
else
ele->type = cJSON_False;
return true;
}
bool json::set_value(const char* key, int val)
{
cJSON* ele = this->find(key);
if (!ele)
return false;
if (ele->type == cJSON_String)
free(ele->valuestring);
ele->type = cJSON_Number;
ele->valuedouble = ele->valueint = val;
return true;
}
bool json::set_value(const char* key, double val)
{
cJSON* ele = this->find(key);
if (!ele)
return false;
if (ele->type == cJSON_String)
free(ele->valuestring);
ele->type = cJSON_Number;
ele->valuedouble = val;
return true;
}
bool json::set_value(const char* key, std::string val)
{
cJSON* ele = this->find(key);
if (!ele)
return false;
if (ele->type == cJSON_String)
free(ele->valuestring);
ele->type = cJSON_String;
ele->valuestring = (char*)malloc(val.length() + 4);
bzero(ele->valuestring, val.length() + 4);
strcpy(ele->valuestring, val.c_str());
return true;
}

View File

@ -1,50 +0,0 @@
#pragma once
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
#endif
#include "cJSON.h"
#include <vector>
#include <string>
class json
{
cJSON *obj_;
cJSON* cur_child_;
cJSON* find_child(cJSON *parent, const char* child_name);
cJSON* find(const char* path);
public:
json(char* json_txt = 0);
~json();
static std::string to_string(cJSON* root);
static std::string get_value_as_string(cJSON* root, bool integer = false);
public:
bool attach_text(char* json_txt);
bool attach_cjson(cJSON* cjson);
void clear(void);
std::string to_string(void);
// can be path: child/value ...
std::string key(void);
bool get_value(const char* key, bool& val);
bool get_value(const char* key, int& val);
bool get_value(const char* key, double& val);
bool get_value(const char* key, std::string& val);
bool get_value(const char* key, json*& val); // caller shoud call "delete" to free the returned object !!!
bool get_value_as_string(const char* key, std::string& val, bool integer);
bool get_as_array(const char* key, std::vector<std::string>& val);
bool first_child(std::string& val);
bool next_child(std::string& val);
bool set_value(const char* key, bool val);
bool set_value(const char* key, int val);
bool set_value(const char* key, double val);
bool set_value(const char* key, std::string val);
};

View File

@ -1,6 +1,7 @@
#include "sane_hg_mdw.h"
#include "json.h"
#include "../sdk/json/gb_json.h"
#include <stdarg.h>
#include <time.h>
#include <fcntl.h>
@ -35,9 +36,6 @@
#define iconv_t void*
#endif
static std::string g_sane_path("");
static std::string g_sane_name(GET_BACKEND_NAME);
namespace local_utility
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -124,7 +122,7 @@ namespace local_utility
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// json parser ...
// gb_json parser ...
bool is_space(char ch)
{
return ch == ' ' || ch == '\t';
@ -433,9 +431,9 @@ namespace local_utility
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static sane_callback cb_ui_ = NULL;
static void* cb_ui_parm_ = NULL;
static SANE_Auth_Callback cb_auth_ = NULL;
static sane_callback cb_ui_ = nullptr;
static void* cb_ui_parm_ = nullptr;
static SANE_Auth_Callback cb_auth_ = nullptr;
static std::mutex cb_lock_;
static std::string sane_event(SANE_Event ev)
@ -461,9 +459,9 @@ namespace local_utility
}
int ui_cb(scanner_handle dev, int code, void* data, unsigned int* len, void* unused)
{
sane_callback cb_ui = NULL;
void* cb_ui_parm = NULL;
SANE_Auth_Callback cb_auth = NULL;
sane_callback cb_ui = nullptr;
void* cb_ui_parm = nullptr;
SANE_Auth_Callback cb_auth = nullptr;
{
std::lock_guard<std::mutex> lck(cb_lock_);
@ -477,7 +475,7 @@ namespace local_utility
SANE_Handle h = hg_sane_middleware::scanner_handle_to_sane(dev);
// local_utility::to_log(LOG_LEVEL_ALL, "sane callback invoked of event %s\n", sane_event((SANE_Event)code).c_str());
// utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane callback invoked of event %s\n", sane_event((SANE_Event)code).c_str());
if (cb_ui)
{
@ -506,9 +504,9 @@ namespace local_utility
void stop_work(void)
{
std::lock_guard<std::mutex> lck(cb_lock_);
cb_ui_ = NULL;
cb_ui_parm_ = NULL;
cb_auth_ = NULL;
cb_ui_ = nullptr;
cb_ui_parm_ = nullptr;
cb_auth_ = nullptr;
}
static void trans_language_if_was_word_id(std::string& val)
@ -538,8 +536,8 @@ namespace local_utility
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
hg_sane_middleware* hg_sane_middleware::inst_ = NULL;
const SANE_Device** hg_sane_middleware::dev_list_ = NULL;
hg_sane_middleware* hg_sane_middleware::inst_ = nullptr;
const SANE_Device** hg_sane_middleware::dev_list_ = nullptr;
hg_sane_middleware::hg_sane_middleware(void) : opt_0_(nullptr), init_ok_(false)
{
@ -548,20 +546,19 @@ hg_sane_middleware::hg_sane_middleware(void) : opt_0_(nullptr), init_ok_(false)
init_ok_ = true;
sprintf(sane_ver, "%u.%u.%u", SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD);
#if defined(WIN32)
hg_scanner_set_sane_info("sane", sane_ver);
#else
signal(SIGUSR1, &hg_sane_middleware::device_pnp);
hg_scanner_set_sane_info(g_sane_name.c_str(), sane_ver);
hg_scanner_initialize(local_utility::ui_cb, NULL);
register_language_changed_notify(&hg_sane_middleware::language_changed, true);
hg_scanner_set_sane_info(GET_BACKEND_NAME, sane_ver);
#endif
hg_scanner_initialize(local_utility::ui_cb, nullptr);
register_language_changed_notify(&hg_sane_middleware::language_changed, true);
#if !defined(WIN32) && !defined(_WIN64)
char path[512] = { 0 };
size_t pos = 0;
g_sane_path = local_utility::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str());
pos = g_sane_path.rfind('/');
if (pos++ != std::string::npos)
g_sane_path.erase(pos);
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait for device OK
}
hg_sane_middleware::~hg_sane_middleware()
{
@ -584,7 +581,7 @@ void hg_sane_middleware::language_changed(int cp, void* param)
// hg_sane_middleware::free_device_inst(v, false);
//
// long count = 0;
// hg_scanner_get_parameter(v->dev, nullptr, NULL, &count);
// hg_scanner_get_parameter(v->dev, nullptr, nullptr, &count);
// for (long ind = 1; ind < count; ++ind)
// hg_sane_middleware::instance()->get_option_descriptor(hg_sane_middleware::scanner_handle_to_sane(v->dev), (void*)ind);
//}
@ -592,8 +589,8 @@ void hg_sane_middleware::language_changed(int cp, void* param)
const SANE_Device** hg_sane_middleware::to_sane_device(ScannerInfo* hgscanner, int count)
{
// 将多级指针安排在一个连续的内存空间存放
SANE_Device** ret = NULL, * dev = NULL;
SANE_String val = NULL;
SANE_Device** ret = nullptr, * dev = nullptr;
SANE_String val = nullptr;
unsigned long bytes = (count + 1) * (sizeof(SANE_Device) + sizeof(SANE_Device*)), total = 0;
// calculate space ...
@ -609,7 +606,7 @@ const SANE_Device** hg_sane_middleware::to_sane_device(ScannerInfo* hgscanner, i
dev = (SANE_Device*)local_utility::acquire_memory(bytes, "hg_sane_middleware::to_sane_device");
total = bytes;
if (!dev)
return NULL;
return nullptr;
memset(dev, 0, bytes);
ret = (SANE_Device**)dev;
@ -631,7 +628,7 @@ const SANE_Device** hg_sane_middleware::to_sane_device(ScannerInfo* hgscanner, i
COPY_DEVICE_MEMBER(type);
}
//local_utility::to_log(LOG_LEVEL_ALL, "Memory usage: %u / %u\n", val - (char*)ret, total);
//utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "Memory usage: %u / %u\n", val - (char*)ret, total);
return (const SANE_Device**)ret;
}
@ -646,7 +643,7 @@ void hg_sane_middleware::free_sane_device(SANE_Device** dev)
}
void hg_sane_middleware::device_pnp(int sig)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "Device list changed (%d)...", sig);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "Device list changed (%d)...", sig);
}
SANE_Fixed hg_sane_middleware::double_2_sane_fixed(double v)
{
@ -701,6 +698,45 @@ std::string hg_sane_middleware::option_value_2_string(SANE_Value_Type type, void
return ret;
}
std::string hg_sane_middleware::string_value_from_json(gb_json* jsn, bool curval)
{
std::string type(""), key(curval ? "cur" : "default");
if (jsn->get_value("type", type))
{
if (type == "bool")
{
bool val = true;
jsn->get_value(key.c_str(), val);
return val ? "true" : "false";
}
else if (type == "int")
{
int val = 0;
jsn->get_value(key.c_str(), val);
return std::to_string(val);
}
else if (type == "float")
{
double val = 0;
jsn->get_value(key.c_str(), val);
return std::to_string(val);
}
else if (type == "string")
{
std::string val("");
jsn->get_value(key.c_str(), val);
return std::move(val);
}
}
return "";
}
scanner_handle hg_sane_middleware::sane_handle_to_scanner(SANE_Handle h)
{
if (!h)
@ -863,7 +899,7 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con
for (size_t i = 0; i < values.size(); ++i)
val[i] = values[i];
}
//local_utility::to_log(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
//utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
return sod;
}
@ -891,7 +927,7 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con
return sod;
}
std::string hg_sane_middleware::get_string_in_json(json* jsn, const char* key, bool* has)
std::string hg_sane_middleware::get_string_in_json(gb_json* jsn, const char* key, bool* has)
{
std::string str("");
int id = -1;
@ -915,9 +951,16 @@ std::string hg_sane_middleware::get_string_in_json(json* jsn, const char* key, b
return std::move(str);
}
std::string hg_sane_middleware::sane_path(void)
void hg_sane_middleware::set_app_callback(void* cb, void* param, int type)
{
return g_sane_path;
if (type == APP_CALLBACK_EX)
local_utility::set_callback((sane_callback)cb, param);
else
local_utility::cb_auth_ = (SANE_Auth_Callback)cb;
}
void hg_sane_middleware::get_version(SANE_Int* ver)
{
local_utility::get_version(ver);
}
hg_sane_middleware* hg_sane_middleware::instance(void)
{
@ -936,7 +979,7 @@ void hg_sane_middleware::clear(void)
if (hg_sane_middleware::inst_)
{
delete hg_sane_middleware::inst_;
hg_sane_middleware::inst_ = NULL;
hg_sane_middleware::inst_ = nullptr;
}
}
@ -951,7 +994,7 @@ void hg_sane_middleware::reload_options(scanner_handle dev)
long count = 0;
hg_sane_middleware::free_device_inst(v, false);
hg_scanner_get_parameter(v->dev, nullptr, NULL, &count);
hg_scanner_get_parameter(v->dev, nullptr, nullptr, &count);
for (long ind = 1; ind < count; ++ind)
{
get_option_descriptor(hg_sane_middleware::scanner_handle_to_sane(v->dev), (void*)ind);
@ -1002,13 +1045,13 @@ void hg_sane_middleware::set_status_by_depends(scanner_handle hdev, SLAVEOP& so,
}
SANE_Status hg_sane_middleware::open(SANE_String_Const devicename, SANE_Handle* handle, const char* name, const char* pwd, const char* method, char* rsc)
{
scanner_handle h = NULL;
scanner_handle h = nullptr;
scanner_err err = SCANNER_ERR_OK;
if (handle == NULL)
if (handle == nullptr)
return SANE_STATUS_INVAL;
err = hg_scanner_open(&h, devicename, false, NULL, NULL, NULL, rsc);
err = hg_scanner_open(&h, devicename, false, nullptr, nullptr, nullptr, rsc);
if (err == SCANNER_ERR_OK)
{
LPDEVINST inst = new DEVINST;
@ -1021,7 +1064,7 @@ SANE_Status hg_sane_middleware::open(SANE_String_Const devicename, SANE_Handle*
if (!local_utility::cb_ui_)
{
long count = 0;
hg_scanner_get_parameter(h, 0, NULL, &count);
hg_scanner_get_parameter(h, 0, nullptr, &count);
inst->std_opt = new sane_std_opts(count);
}
@ -1034,7 +1077,7 @@ SANE_Status hg_sane_middleware::open(SANE_String_Const devicename, SANE_Handle*
else
return (SANE_Status)err; // SANE_STATUS_UNSUPPORTED;
}
SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const std::string& name, json* jsn)
SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const std::string& name, gb_json* jsn)
{
std::string title(hg_sane_middleware::get_string_in_json(jsn, "title")),
desc(hg_sane_middleware::get_string_in_json(jsn, "desc")),
@ -1045,31 +1088,31 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
int opt_val_size = 0;
if (!jsn->get_value("type", val))
return NULL;
return nullptr;
SANE_Option_Descriptor* ret = NULL;
SANE_Option_Descriptor* ret = nullptr;
if (val == "string")
{
json* range = NULL;
gb_json* range = nullptr;
std::vector<std::string> constraints;
jsn->get_value("range", range);
if (range)
{
if (range->first_child(val))
gb_json* child = range->first_child();
while(child)
{
local_utility::trans_language_if_was_word_id(val);
constraints.push_back(val);
opt_val_size = val.length();
while (range->next_child(val))
if (child->value(val))
{
local_utility::trans_language_if_was_word_id(val);
constraints.push_back(val);
if (opt_val_size < val.length())
opt_val_size = val.length();
}
child->release();
child = range->next_child();
}
delete range;
range->release();
}
ret = hg_sane_middleware::string_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
@ -1077,7 +1120,7 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
}
else if (val == "int" || val == "float")
{
json* range = NULL;
gb_json* range = nullptr, * child = nullptr;
jsn->get_value("range", range);
if (range)
@ -1093,20 +1136,21 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
lower = l;
upper = u;
step = s;
local_utility::to_log(LOG_LEVEL_DEBUG, "%s range: [%d, +%d, %d]\n", name.c_str(), l, s, u);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "%s range: [%d, +%d, %d]\n", name.c_str(), l, s, u);
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, false, &lower, &upper, &step);
}
else
{
std::vector<int> constraints;
if (range->first_child(val))
child = range->first_child();
while(child)
{
constraints.push_back(atoi(val.c_str()));
while (range->next_child(val))
{
constraints.push_back(atoi(val.c_str()));
}
int v = 0;
if(child->value(v))
constraints.push_back(v);
child->release();
child = range->next_child();
}
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, constraints);
@ -1119,49 +1163,50 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
range->get_value("max", upper);
step = (upper - lower) / 10.0f;
range->get_value("step", step);
local_utility::to_log(LOG_LEVEL_DEBUG, "%s range: (%f, +%f, %f)\n", name.c_str(), lower, step, upper);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "%s range: (%f, +%f, %f)\n", name.c_str(), lower, step, upper);
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, true, &lower, &upper, &step);
}
else
{
std::vector<double> constraints;
if (range->first_child(val))
child = range->first_child();
while (child)
{
constraints.push_back(atof(val.c_str()));
while (range->next_child(val))
{
constraints.push_back(atof(val.c_str()));
}
double v = .0f;
if (child->value(v))
constraints.push_back(v);
child->release();
child = range->next_child();
}
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, constraints);
}
}
delete range;
range->release();
}
else
{
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, false, NULL, NULL, NULL);
, false, nullptr, nullptr, nullptr);
}
}
else if (val == "bool")
{
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, false, NULL, NULL, NULL);
, false, nullptr, nullptr, nullptr);
ret->type = SANE_TYPE_BOOL;
}
else if (val == "button")
{
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, false, NULL, NULL, NULL);
, false, nullptr, nullptr, nullptr);
ret->type = SANE_TYPE_BUTTON;
}
else if (val == "group")
{
ret = hg_sane_middleware::number_option_to_SANE_descriptor(name.c_str(), title.c_str(), desc.c_str()
, false, NULL, NULL, NULL);
, false, nullptr, nullptr, nullptr);
ret->type = SANE_TYPE_GROUP;
}
@ -1175,7 +1220,7 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
if (bytes < opt_val_size)
{
opt_val_size = ALIGN_INT(opt_val_size + 4);
local_utility::to_log(LOG_LEVEL_DEBUG, "Resize size of '%s' from %d to %d\n", name.c_str(), bytes, opt_val_size);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "Resize size of '%s' from %d to %d\n", name.c_str(), bytes, opt_val_size);
bytes = opt_val_size;
}
ret->size = bytes;
@ -1208,7 +1253,7 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
// ret->cap |= SANE_CAP_INACTIVE;
// å…³è<C2B3>”ï¿?
json* depend = NULL;
gb_json* depend = nullptr;
SLAVEOP so;
if (jsn->get_value("depend_or", depend))
{
@ -1226,31 +1271,9 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
so.enable_now = (ret->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE;
so.name = name;
// initializing status ... move to set_status_by_depends (2023-06-21)
//if (so.master.size())
//{
// //std::string master(get_option_json(h, (void *)so.master[0].name.c_str()));
// //json* m = new json();
// //if (m->attach_text(&master[0]))
// //{
// // bool integer = false, str = false;
//
// // master = "";
// // m->get_value("type", master);
// // integer = master == "int";
// // str = master == "string";
// // master = "";
// // m->get_value_as_string("cur", master, integer);
// // local_utility::trans_language_if_was_word_id(val);
// so.enable_now = so.is_enable(h, so.master, (*it)->cur_vals);
// if (!so.enable_now)
// ret->cap |= SANE_CAP_INACTIVE;
// //}
// //delete m;
//}
(*it)->slaves.push_back(so);
}
delete depend;
depend->release();
}
}
@ -1283,7 +1306,7 @@ scanner_handle hg_sane_middleware::find_openning_device(SANE_Handle h, bool rmv,
std::vector<LPDEVINST>::iterator it = find_openning_device_in_que(handle);
if (it == openning_.end())
handle = NULL;
handle = nullptr;
else
{
if (dev)
@ -1300,7 +1323,7 @@ scanner_handle hg_sane_middleware::find_openning_device(SANE_Handle h, bool rmv,
}
std::string hg_sane_middleware::get_option_json(scanner_handle handle, void *opt, std::string* key, SANE_Int* id)
{
char* json_txt = NULL;
char* json_txt = nullptr;
long length = 0;
scanner_err err = hg_scanner_get_parameter(handle, (const char*)opt, json_txt, &length);
std::string ret("");
@ -1392,7 +1415,7 @@ SANE_Option_Descriptor* hg_sane_middleware::find_stored_descriptor(scanner_handl
}
}
return NULL;
return nullptr;
}
void hg_sane_middleware::reload_current_value(scanner_handle handle, std::vector<std::string>* changed)
@ -1402,19 +1425,19 @@ void hg_sane_middleware::reload_current_value(scanner_handle handle, std::vector
if (changed)
changed->clear();
hg_scanner_get_parameter(handle, 0, NULL, &count);
hg_scanner_get_parameter(handle, 0, nullptr, &count);
for (int i = 1; i < count; ++i)
{
std::string key(""),
val(get_option_json(handle, (void *)i, &key));
json* jsn = new json();
gb_json* jsn = new gb_json();
if (jsn->attach_text(&val[0]) &&
jsn->get_value("type", val))
{
if (refresh_current_value(*it, key.c_str(), jsn))
changed->push_back(key);
}
delete jsn;
jsn->release();
}
}
bool hg_sane_middleware::get_current_value(scanner_handle handle, const void* option, void(*setv)(void*, size_t, void*), void* value, SANE_Value_Type* type)
@ -1447,7 +1470,7 @@ bool hg_sane_middleware::get_current_value(scanner_handle handle, const void* op
std::string name(""),
val(get_option_json(handle, (void *)option, &name));
json* jsn = new json();
gb_json* jsn = new gb_json();
int estimate = 20;
bool ret = false;
@ -1505,10 +1528,10 @@ bool hg_sane_middleware::get_current_value(scanner_handle handle, const void* op
if (setv == &hg_sane_middleware::set_value_to_new)
value = *(void**)value;
local_utility::to_log(LOG_LEVEL_ALL, "<--Get option(%d - %s) value: %s\n", option, val.c_str(), hg_sane_middleware::option_value_2_string(t, value).c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "<--Get option(%d - %s) value: %s\n", option, val.c_str(), hg_sane_middleware::option_value_2_string(t, value).c_str());
}
delete jsn;
jsn->release();
return ret;
}
@ -1516,7 +1539,7 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
{
std::string val(get_option_json(handle, (void *)option));
void* data = nullptr;
json* jsn = new json();
gb_json* jsn = new gb_json();
if (jsn->attach_text(&val[0]) &&
jsn->get_value("type", val))
@ -1542,7 +1565,7 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
*bytes = sizeof(SANE_Bool);
if (log)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "option %d(%s) default value is: %s\n", option, title.c_str(), v ? "true" : "false");
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "option %d(%s) default value is: %s\n", option, title.c_str(), v ? "true" : "false");
}
}
else if (val == "int")
@ -1556,7 +1579,7 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
*bytes = sizeof(v);
if (log)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "option %d(%s) default value is: %d\n", option, title.c_str(), v);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "option %d(%s) default value is: %d\n", option, title.c_str(), v);
}
}
else if (val == "float")
@ -1572,7 +1595,7 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
memcpy(data, &sd, sizeof(sd));
if (log)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "option %d(%s) default value is: %f\n", option, title.c_str(), v);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "option %d(%s) default value is: %f\n", option, title.c_str(), v);
}
}
else if (val == "string")
@ -1590,15 +1613,15 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
*bytes = val.length() + 1;
if (log)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "option %d(%s) default value is: %s\n", option, title.c_str(), (char*)data);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "option %d(%s) default value is: %s\n", option, title.c_str(), (char*)data);
}
}
else
{
local_utility::to_log(LOG_LEVEL_DEBUG, "option %d(%s) is '%s' and no value action.\n", option, title.c_str(), val.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "option %d(%s) is '%s' and no value action.\n", option, title.c_str(), val.c_str());
}
}
delete jsn;
jsn->release();
if (!data)
{
@ -1618,7 +1641,7 @@ SANE_Status hg_sane_middleware::get_devices(const SANE_Device*** device_list, SA
if (!device_list)
return SANE_STATUS_INVAL;
ScannerInfo * dev = NULL;
ScannerInfo * dev = nullptr;
long count = 0;
scanner_err hgerr = hg_scanner_enum(dev, &count, local_only);
SANE_Status ret = SANE_STATUS_GOOD;
@ -1631,7 +1654,7 @@ SANE_Status hg_sane_middleware::get_devices(const SANE_Device*** device_list, SA
if (hgerr != SCANNER_ERR_OK)
{
local_utility::free_memory(dev);
dev = NULL;
dev = nullptr;
}
}
@ -1656,13 +1679,13 @@ SANE_Status hg_sane_middleware::open_device(SANE_String_Const devicename, SANE_H
SANE_Status ret = SANE_STATUS_GOOD;
bzero(rsc, sizeof(rsc));
ret = open(devicename, handle, NULL, NULL, NULL, rsc);
ret = open(devicename, handle, nullptr, nullptr, nullptr, rsc);
if (ret == SANE_STATUS_ACCESS_DENIED && rsc[0])
{
SANEAUTH auth;
bzero(&auth, sizeof(auth));
auth.resource = rsc;
if (local_utility::ui_cb(NULL, SANE_EVENT_NEED_AUTH, (void*)&auth, NULL, NULL))
if (local_utility::ui_cb(nullptr, SANE_EVENT_NEED_AUTH, (void*)&auth, nullptr, nullptr))
{
return SANE_STATUS_CANCELLED;
}
@ -1755,7 +1778,7 @@ SANE_Option_Descriptor* hg_sane_middleware::get_option_descriptor(SANE_Handle h,
opt_0_->type = SANE_TYPE_INT;
opt_0_->size = sizeof(SANE_TYPE_INT);
}
local_utility::to_log(LOG_LEVEL_DEBUG, "get_option_descriptor(0)\n");
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "get_option_descriptor(0)\n");
return opt_0_;
}
@ -1767,7 +1790,7 @@ SANE_Option_Descriptor* hg_sane_middleware::get_option_descriptor(SANE_Handle h,
if (json_txt.length())
{
json* jsn = new json();
gb_json* jsn = new gb_json();
if (jsn->attach_text(&json_txt[0]))
{
ret = from_json(handle, key, jsn);
@ -1791,7 +1814,7 @@ SANE_Option_Descriptor* hg_sane_middleware::get_option_descriptor(SANE_Handle h,
refresh_current_value(*it, ret->name, jsn);
}
}
delete jsn;
jsn->release();
}
if(!ret && (*it)->std_opt)
ret = (*it)->std_opt->get_option(id);
@ -1835,10 +1858,10 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
if (option == 0)
{
long count = 0;
hg_scanner_get_parameter(handle, (const char*)option, NULL, &count);
hg_scanner_get_parameter(handle, (const char*)option, nullptr, &count);
*((SANE_Int*)value) = count;
ret = SANE_STATUS_GOOD;
local_utility::to_log(LOG_LEVEL_WARNING, "get option count = %d.\n", count);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "get option count = %d.\n", count);
}
else
{
@ -1908,7 +1931,7 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
if (action == SANE_ACTION_SET_AUTO && desc && desc->type != SANE_TYPE_BUTTON && desc->type != SANE_TYPE_GROUP) // we assume the driver can set the option properbly, and no work to do
{
local_utility::to_log(LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
int len = 0;
bool can_auto = true;
@ -1939,7 +1962,7 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
SANE_Option_Descriptor* known = dev->std_opt->get_option(id);
unsigned char* cont = (unsigned char*)value;
prev = hg_sane_middleware::option_value_2_string(known->type, value);
local_utility::to_log(LOG_LEVEL_DEBUG, "$First 4-bytes of origin value for option %d is: %02X%02X%02X%02X\n", option, cont[0], cont[1], cont[2], cont[3]);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "$First 4-bytes of origin value for option %d is: %02X%02X%02X%02X\n", option, cont[0], cont[1], cont[2], cont[3]);
err = dev->std_opt->set_value(handle, id, value);
v = hg_sane_middleware::option_value_2_string(known->type, value);
}
@ -1956,14 +1979,14 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
return local_utility::scanner_err_2_sane_statu(hg_scanner_set_parameter(handle, name.c_str(), value, 0));
}
local_utility::to_log(LOG_LEVEL_FATAL, "Option descriptor %d not found.\n", option);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_FATAL, "Option descriptor %d not found.\n", option);
return SANE_STATUS_UNSUPPORTED;
}
else if (!value && desc->type != SANE_TYPE_BUTTON)
{
//if (action == SANE_ACTION_SET_AUTO) // we assume the driver can set the option properbly, and no work to do
//{
// local_utility::to_log(LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
// utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
//
// value = get_default_value(handle, option);
// if (!value)
@ -1972,7 +1995,7 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
//}
//else
{
local_utility::to_log(LOG_LEVEL_WARNING, "Option descriptor %d(%s) need a value!.\n", option, desc->title);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "Option descriptor %d(%s) need a value!.\n", option, desc->title);
return SANE_STATUS_INVAL;
}
@ -2012,11 +2035,11 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
if (prev == v)
{
local_utility::to_log(LOG_LEVEL_ALL, "-->Set option(%d - %s) value: %s\n", option, desc_title.c_str(), v.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "-->Set option(%d - %s) value: %s\n", option, desc_title.c_str(), v.c_str());
}
else
{
local_utility::to_log(LOG_LEVEL_ALL, "-->Set option(%d - %s) value: %s(Applied: %s)\n", option, desc_title.c_str(), prev.c_str(), v.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "-->Set option(%d - %s) value: %s(Applied: %s)\n", option, desc_title.c_str(), prev.c_str(), v.c_str());
}
if (err == SCANNER_ERR_OK)
@ -2029,7 +2052,7 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
}
else if (err == SCANNER_ERR_CONFIGURATION_CHANGED)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "the setting '%s' affects other options value, RELOAD ...\n", desc_title.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "the setting '%s' affects other options value, RELOAD ...\n", desc_title.c_str());
//on_SCANNER_ERR_CONFIGURATION_CHANGED(dev);
if(dev->fixed_id.count(SANE_OPT_ID_LANGUAGE) == 0 || dev->fixed_id[SANE_OPT_ID_LANGUAGE] != id) // language reload by callback already
reload_options(handle);
@ -2037,12 +2060,12 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
}
else if(err == SCANNER_ERR_RELOAD_IMAGE_PARAM)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "the setting '%s' affects image parameter, APP should re-get ...\n", desc_title.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "the setting '%s' affects image parameter, APP should re-get ...\n", desc_title.c_str());
err = (scanner_err)SANE_INFO_RELOAD_PARAMS;
}
else if(err == SCANNER_ERR_RELOAD_OPT_PARAM)
{
local_utility::to_log(LOG_LEVEL_DEBUG, "the setting '%s' affects image parameter and options, APP should re-get image info and reload options...\n", desc_title.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "the setting '%s' affects image parameter and options, APP should re-get image info and reload options...\n", desc_title.c_str());
//on_SCANNER_ERR_CONFIGURATION_CHANGED(dev);
if (dev->fixed_id.count(SANE_OPT_ID_LANGUAGE) == 0 || dev->fixed_id[SANE_OPT_ID_LANGUAGE] != id) // language reload by callback already
reload_options(handle);
@ -2084,7 +2107,7 @@ void* hg_sane_middleware::get_cur_value(SANE_Handle handle, void* option, SANE_V
void* buf = nullptr;
if (!h)
return NULL;
return nullptr;
get_current_value(h, option, &hg_sane_middleware::set_value_to_new, &buf, type);
@ -2095,7 +2118,7 @@ void* hg_sane_middleware::get_def_value(SANE_Handle handle, void* option, int* b
scanner_handle h = find_openning_device(handle);
if (!h)
return NULL;
return nullptr;
return get_default_value(h, option, bytes, log);
}
@ -2113,7 +2136,7 @@ SANE_Status hg_sane_middleware::io_control(SANE_Handle h, unsigned long code, vo
if (ret == SCANNER_ERR_CONFIGURATION_CHANGED)
{
int nc = code;
local_utility::to_log(LOG_LEVEL_DEBUG, "the setting '0x%08x' affects other options value, RELOAD ...\n", nc);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "the setting '0x%08x' affects other options value, RELOAD ...\n", nc);
on_SCANNER_ERR_CONFIGURATION_CHANGED(dev);
}
@ -2169,7 +2192,7 @@ bool hg_sane_middleware::is_enable_and(scanner_handle hdev, const std::vector<MA
std::vector<CURVAL>::iterator it = std::find(curvals.begin(), curvals.end(), master[i].name);
if (it == curvals.end())
{
local_utility::to_log(LOG_LEVEL_WARNING, "option %s's current value is not found, other options depend it maybe in wrong status.\n", master[i].name.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "option %s's current value is not found, other options depend it maybe in wrong status.\n", master[i].name.c_str());
continue;
}
@ -2191,7 +2214,7 @@ bool hg_sane_middleware::is_enable_or(scanner_handle hdev, const std::vector<MAS
std::vector<CURVAL>::iterator it = std::find(curvals.begin(), curvals.end(), master[i].name);
if (it == curvals.end())
{
local_utility::to_log(LOG_LEVEL_WARNING, "option %s's current value is not found, other options depend it maybe in wrong status.\n", master[i].name.c_str());
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_WARNING, "option %s's current value is not found, other options depend it maybe in wrong status.\n", master[i].name.c_str());
continue;
}
@ -2303,17 +2326,16 @@ bool hg_sane_middleware::parse_master_option(const char* depend_str, MASTEROP& m
return ret;
}
bool hg_sane_middleware::parse_depends(scanner_handle h, json* jsn, SLAVEOP& so, std::vector<std::string>& master)
bool hg_sane_middleware::parse_depends(scanner_handle h, gb_json* jsn, SLAVEOP& so, std::vector<std::string>& master)
{
std::string val(""), mn("");
bool ret = jsn->first_child(val);
gb_json* child = jsn->first_child();
while(ret)
while(child)
{
MASTEROP mo;
ret = parse_master_option(val.c_str(), mo);
if (!ret)
if (!child->value(val) || !parse_master_option(val.c_str(), mo))
break;
if (mo.name.empty())
@ -2330,8 +2352,11 @@ bool hg_sane_middleware::parse_depends(scanner_handle h, json* jsn, SLAVEOP& so,
master.push_back(mo.name);
std::sort(master.begin(), master.end());
}
ret = jsn->next_child(val);
child->release();
child = jsn->next_child();
}
if (child)
child->release();
return so.master.size() > 0;
}
@ -2404,7 +2429,7 @@ int hg_sane_middleware::something_after_do(LPDEVINST dev, const char* master_nam
continue;
OPTEN* op = get_control_enalbe_data(dev, dev->slaves[slave]);
hg_scanner_control(dev->dev, HG_CONTROL_CODE_OPTION_ENABLE, op, NULL);
hg_scanner_control(dev->dev, HG_CONTROL_CODE_OPTION_ENABLE, op, nullptr);
free_control_enable_data(op);
if (std::find(changed_options.begin(), changed_options.end(), dev->slaves[slave].name) != changed_options.end())
@ -2421,7 +2446,7 @@ int hg_sane_middleware::something_after_do(LPDEVINST dev, const char* master_nam
return after;
}
bool hg_sane_middleware::refresh_current_value(LPDEVINST dev, const char* name, json* jsn)
bool hg_sane_middleware::refresh_current_value(LPDEVINST dev, const char* name, gb_json* jsn)
{
std::vector<CURVAL>::iterator it = std::find(dev->cur_vals.begin(), dev->cur_vals.end(), name);
if (it == dev->cur_vals.end())
@ -2429,7 +2454,7 @@ bool hg_sane_middleware::refresh_current_value(LPDEVINST dev, const char* name,
CURVAL cv;
jsn->get_value("type", cv.type);
cv.name = name;
jsn->get_value_as_string("cur", cv.val, cv.type == "int");
cv.val = hg_sane_middleware::string_value_from_json(jsn, true);
if (cv.type == "string")
local_utility::trans_language_if_was_word_id(cv.val);
dev->cur_vals.push_back(cv);
@ -2439,7 +2464,7 @@ bool hg_sane_middleware::refresh_current_value(LPDEVINST dev, const char* name,
else
{
std::string old(it->val);
jsn->get_value_as_string("cur", it->val, it->type == "int");
it->val = hg_sane_middleware::string_value_from_json(jsn, true);
if (it->type == "string")
local_utility::trans_language_if_was_word_id(it->val);
@ -2463,7 +2488,7 @@ bool hg_sane_middleware::refresh_current_value(LPDEVINST dev, const char* name,
OPTEN* hg_sane_middleware::get_control_enalbe_data(LPDEVINST dev, const SLAVEOP& slave)
{
std::vector<std::string> master;
OPTEN* opt = NULL;
OPTEN* opt = nullptr;
size_t size = sizeof(OPTEN);
for (size_t i = 0; i < slave.master.size(); ++i)
@ -2552,147 +2577,3 @@ std::vector<LPDEVINST>::iterator hg_sane_middleware::find_openning_device_in_que
return openning_.end();
}
/// </summary>
/// <summary>
/// 导出接口
/// </summary>
extern "C" { // avoid compiler exporting name in C++ style !!!
const char* inner_sane_err_desc(SANE_Status err)
{
return hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err));
}
SANE_Status inner_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize)
{
local_utility::cb_auth_ = authorize;
if (!hg_sane_middleware::instance()->is_ready())
return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST;
local_utility::get_version(version_code);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
return SANE_STATUS_GOOD;
}
void inner_sane_exit(void)
{
hg_sane_middleware::clear();
}
SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only)
{
SANE_Status code = hg_sane_middleware::instance()->get_devices(device_list, local_only);
return code;
}
SANE_Status inner_sane_open(SANE_String_Const devicename, SANE_Handle* handle)
{
return hg_sane_middleware::instance()->open_device(devicename, handle);
}
void inner_sane_close(SANE_Handle handle)
{
hg_sane_middleware::instance()->close_device(handle);
}
const SANE_Option_Descriptor*
inner_sane_get_option_descriptor(SANE_Handle handle, const void* option)
{
return hg_sane_middleware::instance()->get_option_descriptor(handle, option);
}
SANE_Status inner_sane_control_option(SANE_Handle handle, const void* option, SANE_Action action, void* value, SANE_Int* info)
{
return hg_sane_middleware::instance()->set_option(handle, option, action, value, info);
}
SANE_Status inner_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params)
{
return hg_sane_middleware::instance()->get_image_parameters(handle, params);
}
SANE_Status inner_sane_start(SANE_Handle handle)
{
local_utility::to_log(LOG_LEVEL_ALL, "sane_start\n");
return hg_sane_middleware::instance()->start(handle, NULL);
}
SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length)
{
if (!length)
length = &max_length;
else
*length = max_length;
return hg_sane_middleware::instance()->read(handle, data, length);
}
void inner_sane_cancel(SANE_Handle handle)
{
local_utility::to_log(LOG_LEVEL_ALL, "sane_cancel\n");
hg_sane_middleware::instance()->stop(handle);
}
SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
{
local_utility::to_log(LOG_LEVEL_ALL, "sane_set_io_mode\n");
return non_blocking ? SANE_STATUS_UNSUPPORTED : SANE_STATUS_GOOD;
}
SANE_Status inner_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd)
{
return SANE_STATUS_UNSUPPORTED;
}
SANE_String_Const inner_sane_strstatus(SANE_Status status)
{
// return hg_scanner_err_name(status);
return inner_sane_err_desc(status);
}
SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param)
{
local_utility::set_callback(cb, param);
if (!hg_sane_middleware::instance()->is_ready())
return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST;
local_utility::get_version(version_code);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
return SANE_STATUS_GOOD;
}
SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len)
{
return hg_sane_middleware::instance()->io_control(h, code, data, len);
}
SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len)
{
return SANE_STATUS_UNSUPPORTED;
}
void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap)
{
}
}
#if defined(WIN32) || defined(_WIN64)
HMODULE g_my_inst = NULL;
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
g_my_inst = inst;
if (g_sane_path.empty())
{
char path[MAX_PATH] = { 0 };
GetModuleFileNameA(inst, path, _countof(path) - 1);
if (strrchr(path, '\\'))
{
g_sane_name = strrchr(path, '\\') + 1;
strrchr(path, '\\')[1] = 0;
g_sane_path = path;
if (g_sane_name.rfind('.') != std::string::npos)
g_sane_name.erase(g_sane_name.rfind('.'));
}
}
}
else if (reason == DLL_PROCESS_DETACH)
{
inner_sane_exit();
}
return TRUE;
}
#endif

View File

@ -25,7 +25,7 @@
#define hg_sane_middleware lsc_sane_middleware
#endif
class json;
class gb_json;
class sane_std_opts;
typedef struct _device_option
{
@ -144,7 +144,7 @@ class hg_sane_middleware
void reload_options(scanner_handle dev = nullptr);
void set_status_by_depends(scanner_handle hdev, SLAVEOP& so, std::vector<CURVAL>& vals, SANE_Option_Descriptor* desc);
SANE_Status open(SANE_String_Const devicename, SANE_Handle* handle, const char* name, const char* pwd, const char* method, char* rsc);
SANE_Option_Descriptor* from_json(scanner_handle h, const std::string& name, json* jsn);
SANE_Option_Descriptor* from_json(scanner_handle h, const std::string& name, gb_json* jsn);
std::string get_option_json(scanner_handle handle, void* opt, std::string* key = nullptr, SANE_Int* id = nullptr);
SANE_Option_Descriptor* find_stored_descriptor(scanner_handle handle, const void* option, SANE_Int* id = nullptr, SANE_Int* fix_id = nullptr);
@ -157,7 +157,7 @@ class hg_sane_middleware
// 添加对多依赖项的支持 - 2022-03-10
//std::vector<CURVAL> cur_vals_;
bool refresh_current_value(LPDEVINST dev, const char* name, json* jsn); // return whether changed old value
bool refresh_current_value(LPDEVINST dev, const char* name, gb_json* jsn); // return whether changed old value
bool refresh_current_value(LPDEVINST dev, const char* name, const char* val);
static bool compare_val_equal(const char* cur_val, const char* limit_l, const char* limit_r);
@ -176,7 +176,7 @@ class hg_sane_middleware
bool parse_master_option(const char* depend_str, MASTEROP& mo);
bool parse_depends(scanner_handle h, json* jsn, SLAVEOP& so, std::vector<std::string>& master);
bool parse_depends(scanner_handle h, gb_json* jsn, SLAVEOP& so, std::vector<std::string>& master);
bool is_associatived(const SLAVEOP& slave, const char* master_name);
bool set_stored_option_enabled(scanner_handle h, const void* option, bool enable, int* size = NULL);
@ -198,11 +198,19 @@ protected:
~hg_sane_middleware();
public:
static std::string sane_path(void);
enum
{
APP_CALLBACK_AUTH = 0,
APP_CALLBACK_EX,
};
static void set_app_callback(void* cb, void* param = nullptr, int type = APP_CALLBACK_AUTH);
static void get_version(SANE_Int* ver);
static hg_sane_middleware* instance(void);
static void set_callback(sane_callback cb, void* param);
static void clear(void);
static std::string option_value_2_string(SANE_Value_Type type, void* val);
static std::string string_value_from_json(gb_json* jsn, bool curval);
static scanner_handle sane_handle_to_scanner(SANE_Handle h);
static SANE_Handle scanner_handle_to_sane(scanner_handle h);
static SANE_Option_Descriptor* allocate_descriptor(const char* name, const char* title, const char* desc);
@ -215,7 +223,7 @@ public:
, const std::vector<int>& values); // NO constraint if values was empty
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
, const std::vector<double>& values); // NO constraint if values was empty
static std::string get_string_in_json(json* jsn, const char* key, bool* has = nullptr);
static std::string get_string_in_json(gb_json* jsn, const char* key, bool* has = nullptr);
// methods ...
public:

View File

@ -3,6 +3,7 @@
#include <sane/sane_option_definitions.h>
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "../sdk/hginclude/utils.h"
#include "../sdk/json/gb_json.h"
#include "../../sdk/include/lang/app_language.h"
@ -52,7 +53,7 @@ static void match_paper(char* buf, int cx, int cy)
else
strcpy(buf, from_default_language(g_paper[index].title, NULL));
local_utility::to_log(LOG_LEVEL_DEBUG, "match paper(%u * %u) to '%s'\n", cx, cy, (char*)buf);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "match paper(%u * %u) to '%s'\n", cx, cy, (char*)buf);
}
@ -174,11 +175,11 @@ void* sane_std_opts::from_known_opt_value(OPTMAP* opmap, const void* known_data,
return buf;
}
json* sane_std_opts::get_opt_json(scanner_handle h, int opt)
gb_json* sane_std_opts::get_opt_json(scanner_handle h, int opt)
{
char* buf = nullptr;
long len = 0;
json* jsn = nullptr;
gb_json* jsn = nullptr;
if (hg_scanner_get_parameter(h, (const char*)opt, buf, &len) == SCANNER_ERR_INSUFFICIENT_MEMORY)
{
@ -186,10 +187,10 @@ json* sane_std_opts::get_opt_json(scanner_handle h, int opt)
memset(buf, 0, len + 8);
if (hg_scanner_get_parameter(h, (const char*)opt, buf, &len) == SCANNER_ERR_OK)
{
jsn = new json();
jsn = new gb_json();
if (!jsn->attach_text(buf))
{
delete jsn;
jsn->release();
jsn = nullptr;
}
}
@ -200,7 +201,7 @@ json* sane_std_opts::get_opt_json(scanner_handle h, int opt)
}
void* sane_std_opts::get_current_value(scanner_handle h, int opt)
{
json* jsn = sane_std_opts::get_opt_json(h, opt);
gb_json* jsn = sane_std_opts::get_opt_json(h, opt);
void* ret = nullptr;
if (jsn)
@ -238,7 +239,7 @@ void* sane_std_opts::get_current_value(scanner_handle h, int opt)
ret = local_utility::acquire_memory(sizeof(SANE_Fixed), "");
*((SANE_Fixed*)ret) = SANE_FIX(v);
}
delete jsn;
jsn->release();
}
return ret;
@ -397,7 +398,7 @@ scanner_err sane_std_opts::set_value(scanner_handle h, int opt, void* buf)
long len = 0;
void* data = from_known_opt_value(op, buf, &len);
local_utility::to_log(LOG_LEVEL_DEBUG, "%d->%d: %s\n", opt, op->user.opt, (char*)data);
utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_DEBUG, "%d->%d: %s\n", opt, op->user.opt, (char*)data);
statu = hg_scanner_set_parameter(h, (const char*)op->user.opt, data, &len);
if (statu == SCANNER_ERR_NOT_EXACT)

View File

@ -14,25 +14,15 @@
#endif
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "sane/sane_ex.h"
#include "json.h"
#include <memory>
namespace local_utility
{
void* acquire_memory(size_t bytes, const char* info);
void free_memory(void* m);
template<typename ... Args>
void to_log(int level, const char* fmt, Args ... args)
{
size_t size = snprintf(nullptr, 0, fmt, args ...) + 2;
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), size, fmt, args ...);
hg_scanner_log(buf.get(), level);
}
};
class gb_json;
class sane_std_opts
{
typedef struct _sane_opt
@ -61,7 +51,7 @@ public:
~sane_std_opts();
public:
static json* get_opt_json(scanner_handle h, int opt); // call delete to free the returned object
static gb_json* get_opt_json(scanner_handle h, int opt); // call delete to free the returned object
static void* get_current_value(scanner_handle h, int opt); // call local_utility::free_memory to free the returned buffer
public:

View File

@ -839,6 +839,38 @@ namespace utils
return str.c_str();
}
HMODULE load_dll(const char* path_file, int flag)
{
#if OS_WIN
HMODULE h = LoadLibraryA(path_file);
int ret = GetLastError();
utils::to_log(1, "[TWAIN]Load: LoadLibraryA(%s) = %d\r\n", path_file, ret);
if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT))
{
std::string dir(path_file);
size_t pos = dir.rfind('\\');
char path[MAX_PATH] = { 0 };
GetDllDirectoryA(_countof(path) - 1, path);
if (pos != std::wstring::npos)
dir.erase(pos);
utils::to_log(LOG_LEVEL_FATAL, "[TWAIN]Load: change directory to '%s' and retry LoadLibraryA(%s) ...\r\n", dir.c_str(), path_file);
SetDllDirectoryA(dir.c_str());
h = LoadLibraryA(path_file);
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
ret = GetLastError();
utils::to_log(1, "[TWAIN]Load: trying LoadLibraryA(%s) = %d, restore directory to '%s'\r\n", path_file, ret, path);
SetDllDirectoryA(path);
}
errno = GetLastError();
return h;
#else
return dlopen(path_file, flag);
#endif
}
bool create_folder(const char* folder)
{
int ret = MKDIR(folder, S_IREAD | S_IWRITE | S_IEXEC);

View File

@ -43,6 +43,7 @@ namespace utils
const char* to_lower(std::string& str); // return str.c_str()
const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str()
HMODULE load_dll(const char* path_file, int flag);
bool create_folder(const char* folder);
void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file);
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
@ -72,6 +73,19 @@ namespace utils
log_info(buf.get(), (log_level)level);
}
}
template<typename ... Args>
void to_log_with_api(bool(*is_enable)(int), void(*log_api)(const char*, int), int level, const char* fmt, Args ... args)
{
if (is_enable(level))
{
size_t size = snprintf(nullptr, 0, fmt, args ...) + 2;
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), size, fmt, args ...);
log_api(buf.get(), (log_level)level);
}
}
};
#if OS_WIN

View File

@ -776,19 +776,19 @@ cJSON *cJSON_Duplicate(cJSON *item,int recurse)
return newitem;
}
void cJSON_Minify(char *json)
void cJSON_Minify(char *gb_json)
{
char *into=json;
while (*json)
char *into=gb_json;
while (*gb_json)
{
if (*json==' ') json++;
else if (*json=='\t') json++; /* Whitespace characters. */
else if (*json=='\r') json++;
else if (*json=='\n') json++;
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; /* double-slash comments, to end of line. */
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} /* multiline comments. */
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */
else *into++=*json++; /* All other characters. */
if (*gb_json==' ') gb_json++;
else if (*gb_json=='\t') gb_json++; /* Whitespace characters. */
else if (*gb_json=='\r') gb_json++;
else if (*gb_json=='\n') gb_json++;
else if (*gb_json=='/' && gb_json[1]=='/') while (*gb_json && *gb_json!='\n') gb_json++; /* double-slash comments, to end of line. */
else if (*gb_json=='/' && gb_json[1]=='*') {while (*gb_json && !(*gb_json=='*' && gb_json[1]=='/')) gb_json++;gb_json+=2;} /* multiline comments. */
else if (*gb_json=='\"'){*into++=*gb_json++;while (*gb_json && *gb_json!='\"'){if (*gb_json=='\\') *into++=*gb_json++;*into++=*gb_json++;}*into++=*gb_json++;} /* string literals, which are \" sensitive. */
else *into++=*gb_json++; /* All other characters. */
}
*into=0; /* and null-terminate. */
}

View File

@ -133,7 +133,7 @@ The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
extern void cJSON_Minify(char *json);
extern void cJSON_Minify(char *gb_json);
// convert e681a2 to \u6062, call 'free' to free the returned value
extern char* cJSON_utf8_2_unic(const char* utf8);

817
sdk/json/gb_json.cpp Normal file
View File

@ -0,0 +1,817 @@
#include "gb_json.h"
#include "cJSON.h"
#include <stdlib.h>
#include <string.h>
namespace special_char_trans
{
struct
{
const char* writedown_text;
char readable_char;
}transferred_chars[] = { { "\\\"", '\"' }
, { "\\'", '\'' }
, { "\\a", '\a' }
, { "\\b", '\b' }
, { "\\f", '\f' }
, { "\\n", '\n' }
, { "\\r", '\r' }
, { "\\t", '\t' }
, { "\\v", '\v' }
// , { "\\?", '\?' }
, { "\\\\", '\\' }
, { "\\/", '/' }
// , { "\\0", '\0' }
};
void to_writedown(std::string& str)
{
std::string trans(str);
const char* ptr = trans.c_str();
str.clear();
while (*ptr)
{
bool rep = false;
if (*ptr == '\\')
{
if (ptr[1] == '\\')
{
str += "\\\\";
ptr++;
rep = true;
}
else if( ptr[1] == '/' ||
ptr[1] == 'a' ||
ptr[1] == 'b' ||
ptr[1] == 'f' ||
ptr[1] == 'n' ||
ptr[1] == 'r' ||
ptr[1] == 't' ||
ptr[1] == 'u' ||
ptr[1] == 'v')
{
str += "\\";
ptr++;
}
else
{
str += "\\\\";
rep = true;
}
}
else
{
for (size_t i = 0; i < sizeof(transferred_chars) / sizeof(transferred_chars[0]); ++i)
{
if (*ptr == transferred_chars[i].readable_char)
{
str += transferred_chars[i].writedown_text;
rep = true;
break;
}
}
}
if (!rep)
str.append(1, *ptr);
ptr++;
}
}
}
gb_json::gb_json(char* json_txt) : ref_(1), type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1)
{
simple_val_.dval = .0f;
if(json_txt)
attach_text(json_txt);
}
gb_json::gb_json(const char* key, bool val) : ref_(1), type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1)
{
simple_val_.bval = val;
}
gb_json::gb_json(const char* key, int val) : ref_(1), type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1)
{
simple_val_.nval = val;
}
gb_json::gb_json(const char* key, double val) : ref_(1), type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1)
{
simple_val_.dval = val;
}
gb_json::gb_json(const char* key, const char* val) : ref_(1), type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1)
{}
gb_json::~gb_json()
{
clear();
}
std::string gb_json::object_key(gb_json* jsn)
{
return "\"" + jsn->key() + "\":";
}
std::string gb_json::array_key(gb_json* jsn)
{
return "";
}
void gb_json::from_cjson(cJSON* cj)
{
key_ = cj && cj->string ? cj->string : "";
while (cj)
{
gb_json* child = nullptr;
if (cj->type == cJSON_True)
{
child = new gb_json(cj->string, true);
}
else if(cj->type == cJSON_False)
{
child = new gb_json(cj->string, false);
}
else if (cj->type == cJSON_Number)
{
if (cj->valuedouble - (int)cj->valuedouble < .00001)
{
child = new gb_json(cj->string, cj->valueint);
}
else
{
child = new gb_json(cj->string, cj->valuedouble);
}
}
else if (cj->type == cJSON_String)
{
child = new gb_json(cj->string, cj->valuestring);
}
else if (cj->type == cJSON_Object || cj->type == cJSON_Array)
{
child = new gb_json();
child->from_cjson(cj->child);
child->key_ = cj->string ? cj->string : "";
}
arr_val_.push_back(child);
cj = cj->next;
}
if (arr_val_.size() == 1 && arr_val_[0]->arr_val_.size() == 0)
{
gb_json* child = arr_val_[0];
if (!child->key_.empty()) // array
{
arr_val_.clear();
type_ = child->type_;
key_ = child->key_;
simple_val_.dval = child->simple_val_.dval;
strval_ = child->strval_;
for (auto& v : child->arr_val_)
arr_val_.push_back(v);
child->arr_val_.clear();
child->release();
}
}
if (arr_val_.size())
{
type_ = arr_val_[0]->key().empty() ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT;
}
}
gb_json* gb_json::find_child(const char* key, bool remove)
{
gb_json* ret = nullptr;
if (type_ == VAL_TYPE_OBJECT)
{
for (size_t i = 0; i < arr_val_.size(); ++i)
{
if (arr_val_[i]->key() == key)
{
ret = arr_val_[i];
if (remove)
arr_val_.erase(arr_val_.begin() + i);
else
ret->add_ref();
break;
}
}
}
return ret;
}
int32_t gb_json::add_ref()
{
std::lock_guard<std::mutex> lock(ref_mutex_);
int32_t ref = ++ref_;
return ref;
}
int32_t gb_json::release()
{
int32_t ref = 0;
{
std::lock_guard<std::mutex> lock(ref_mutex_);
ref = --ref_;
}
if (ref == 0)
delete this;
return ref;
}
bool gb_json::attach_text(char* json_txt)
{
clear();
cJSON* jsn = cJSON_Parse(json_txt);
if (jsn)
{
char *text = cJSON_Print(jsn);
if (text)
free(text);
from_cjson(jsn->child);
cJSON_Delete(jsn);
return true;
}
return false;
}
void gb_json::clear(bool as_array)
{
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
{
for (auto& v : arr_val_)
v->release();
}
type_ = as_array ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT;
simple_val_.dval = .0f;
key_ = "";
strval_ = "";
arr_val_.clear();
cur_child_ = -1;
}
std::string gb_json::to_string(void)
{
if (type_ == VAL_TYPE_NULL)
return "";
if (type_ == VAL_TYPE_BOOL)
return (simple_val_.bval ? "true" : "false");
if (type_ == VAL_TYPE_INT)
return std::to_string(simple_val_.nval);
if (type_ == VAL_TYPE_FLOAT)
return std::to_string(simple_val_.dval);
if (type_ == VAL_TYPE_STRING)
{
char* u = cJSON_utf8_2_unic(strval_.c_str());
std::string r(u);
free(u);
special_char_trans::to_writedown(r);
return "\"" + r + "\"";
}
std::string(*k)(gb_json*) = type_ == VAL_TYPE_OBJECT ? gb_json::object_key : gb_json::array_key;
std::string str(type_ == VAL_TYPE_OBJECT ? "{" : "[");
if (arr_val_.size())
{
str += k(arr_val_[0]) + arr_val_[0]->to_string();
for(size_t i = 1; i < arr_val_.size(); ++i)
str += "," + k(arr_val_[i]) + arr_val_[i]->to_string();
}
str += type_ == VAL_TYPE_OBJECT ? "}" : "]";
return str;
}
std::string& gb_json::key(void)
{
return key_;
}
bool gb_json::is_array(void)
{
return type_ == VAL_TYPE_ARRAY;
}
bool gb_json::is_leaf_node(void)
{
return type_ == VAL_TYPE_BOOL ||
type_ == VAL_TYPE_INT ||
type_ == VAL_TYPE_FLOAT ||
type_ == VAL_TYPE_STRING;
}
bool gb_json::get_value(const char* key, bool& val)
{
bool ret = false;
gb_json* child = find_child(key);
if (child)
{
if (child->type_ == VAL_TYPE_BOOL)
{
val = child->simple_val_.bval;
ret = true;
}
child->release();
}
else if (type_ == VAL_TYPE_BOOL && key_ == key)
{
val = simple_val_.bval;
ret = true;
}
return ret;
}
bool gb_json::get_value(const char* key, int& val)
{
bool ret = false;
gb_json* child = find_child(key);
if (child)
{
if (child->type_ == VAL_TYPE_INT)
{
val = child->simple_val_.nval;
ret = true;
}
child->release();
}
else if (type_ == VAL_TYPE_INT && key_ == key)
{
val = simple_val_.nval;
ret = true;
}
return ret;
}
bool gb_json::get_value(const char* key, double& val)
{
bool ret = false;
gb_json* child = find_child(key);
if (child)
{
if (child->type_ == VAL_TYPE_FLOAT)
{
val = child->simple_val_.dval;
ret = true;
}
child->release();
}
else if (type_ == VAL_TYPE_FLOAT && key_ == key)
{
val = simple_val_.dval;
ret = true;
}
// added on 2023-04-27: for cJSON consider both int and float as CJSON_Number, we consider int if the value is just an integer
if(!ret)
{
int v = 0;
ret = get_value(key, v);
if(ret)
val = v;
}
return ret;
}
bool gb_json::get_value(const char* key, std::string& val)
{
bool ret = false;
gb_json* child = find_child(key);
if (child)
{
if (child->type_ == VAL_TYPE_STRING)
{
val = child->strval_;
ret = true;
}
child->release();
}
else if (type_ == VAL_TYPE_STRING && key_ == key)
{
val = strval_;
ret = true;
}
return ret;
}
bool gb_json::get_value(const char* key, gb_json*& val)
{
bool ret = false;
gb_json *child = find_child(key);
if (child)
{
if (child->type_ == VAL_TYPE_OBJECT || child->type_ == VAL_TYPE_ARRAY)
{
val = child;
ret = true;
}
else
{
child->release();
}
}
return ret;
}
size_t gb_json::children(void)
{
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
return arr_val_.size();
else
return -1;
}
gb_json* gb_json::child(size_t ind)
{
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
{
if (ind >= 0 && ind < arr_val_.size())
{
arr_val_[ind]->add_ref();
return arr_val_[ind];
}
}
return nullptr;
}
gb_json* gb_json::first_child(void)
{
if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY)
{
cur_child_ = 0;
if (arr_val_.size())
{
arr_val_[0]->add_ref();
return arr_val_[0];
}
}
return nullptr;
}
gb_json* gb_json::next_child(void)
{
if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY)
{
if (++cur_child_ < arr_val_.size())
{
arr_val_[cur_child_]->add_ref();
return arr_val_[cur_child_];
}
}
return nullptr;
}
bool gb_json::set_value(const char* key, bool val)
{
if (type_ != VAL_TYPE_OBJECT)
return false;
gb_json* child = find_child(key);
if (child)
{
child->clear();
child->type_ = VAL_TYPE_BOOL;
child->key() = key ? key : "";
child->simple_val_.bval = val;
child->release();
}
else
{
child = new gb_json(key, val);
arr_val_.push_back(child);
}
return true;
}
bool gb_json::set_value(const char* key, int val)
{
if (type_ != VAL_TYPE_OBJECT)
return false;
gb_json* child = find_child(key);
if (child)
{
child->clear();
child->type_ = VAL_TYPE_INT;
child->key() = key ? key : "";
child->simple_val_.nval = val;
child->release();
}
else
{
child = new gb_json(key, val);
arr_val_.push_back(child);
}
return true;
}
bool gb_json::set_value(const char* key, double val)
{
if (type_ != VAL_TYPE_OBJECT)
return false;
gb_json* child = find_child(key);
if (child)
{
child->clear();
child->type_ = VAL_TYPE_FLOAT;
child->key() = key ? key : "";
child->simple_val_.dval = val;
child->release();
}
else
{
child = new gb_json(key, val);
arr_val_.push_back(child);
}
return true;
}
bool gb_json::set_value(const char* key, const char* val)
{
if (type_ != VAL_TYPE_OBJECT)
return false;
gb_json* child = find_child(key);
if (child)
{
child->clear();
child->type_ = VAL_TYPE_STRING;
child->key() = key ? key : "";
child->strval_ = val ? val : "";
child->release();
}
else
{
child = new gb_json(key, val);
arr_val_.push_back(child);
}
return true;
}
bool gb_json::set_value(const char* key, gb_json* val)
{
if (type_ != VAL_TYPE_OBJECT)
return false;
for (size_t i = 0; i < arr_val_.size(); ++i)
{
if (arr_val_[i]->key() == key)
{
arr_val_[i]->release();
arr_val_[i] = val;
val->add_ref();
return true;
}
}
arr_val_.push_back(val);
val->key() = key;
val->add_ref();
return true;
}
gb_json& gb_json::operator+=(bool val)
{
if (type_ == VAL_TYPE_ARRAY)
{
gb_json* child = new gb_json(nullptr, val);
arr_val_.push_back(child);
}
return *this;
}
gb_json& gb_json::operator+=(int val)
{
if (type_ == VAL_TYPE_ARRAY)
{
gb_json* child = new gb_json(nullptr, val);
arr_val_.push_back(child);
}
return *this;
}
gb_json& gb_json::operator+=(double val)
{
if (type_ == VAL_TYPE_ARRAY)
{
gb_json* child = new gb_json(nullptr, val);
arr_val_.push_back(child);
}
return *this;
}
gb_json& gb_json::operator+=(const char* val)
{
if (type_ == VAL_TYPE_ARRAY)
{
gb_json* child = new gb_json(nullptr, val);
arr_val_.push_back(child);
}
return *this;
}
gb_json& gb_json::operator+=(gb_json* val)
{
if (type_ == VAL_TYPE_ARRAY)
{
val->add_ref();
arr_val_.push_back(val);
}
return *this;
}
gb_json& gb_json::operator-=(int ind)
{
remove(ind);
return *this;
}
bool gb_json::remove(const char* key)
{
gb_json* child = find_child(key, true);
if (child)
{
child->release();
return true;
}
else
{
return false;
}
}
bool gb_json::remove(gb_json* child)
{
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
{
for (size_t i = 0; i < arr_val_.size(); ++i)
{
if (arr_val_[i] == child)
{
arr_val_[i]->release();
arr_val_.erase(arr_val_.begin() + i);
return true;
}
}
}
return false;
}
bool gb_json::remove(int ind)
{
bool ret = false;
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
{
if (ind >= 0 && ind < arr_val_.size())
{
arr_val_[ind]->release();
arr_val_.erase(arr_val_.begin() + ind);
ret = true;
}
}
return ret;
}
int gb_json::index(gb_json* child)
{
if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT)
{
for (int i = 0; i < arr_val_.size(); ++i)
{
if (arr_val_[i] == child)
return i;
}
}
return -1;
}
int gb_json::index_move_to(gb_json* child, int ind)
{
int i = index(child);
if (i == -1)
return -1;
arr_val_.erase(arr_val_.begin() + i);
if (ind < 0)
ind = 0;
if (ind > arr_val_.size())
ind = arr_val_.size();
arr_val_.insert(arr_val_.begin() + ind, child);
return ind;
}
bool gb_json::value(bool& val)
{
bool ret = false;
if (is_leaf_node() && type_ == VAL_TYPE_BOOL)
{
val = simple_val_.bval;
ret = true;
}
return ret;
}
bool gb_json::value(int& val)
{
bool ret = false;
if (is_leaf_node() && type_ == VAL_TYPE_INT)
{
val = simple_val_.nval;
ret = true;
}
return ret;
}
bool gb_json::value(double& val)
{
bool ret = false;
if (is_leaf_node() && type_ == VAL_TYPE_FLOAT)
{
val = simple_val_.dval;
ret = true;
}
return ret;
}
bool gb_json::value(std::string& val)
{
bool ret = false;
if (is_leaf_node() && type_ == VAL_TYPE_STRING)
{
val = strval_;
ret = true;
}
return ret;
}
gb_json& gb_json::operator=(bool val)
{
if (is_leaf_node())
{
simple_val_.bval = val;
type_ = VAL_TYPE_BOOL;
}
return *this;
}
gb_json& gb_json::operator=(int val)
{
if (is_leaf_node())
{
simple_val_.nval = val;
type_ = VAL_TYPE_INT;
}
return *this;
}
gb_json& gb_json::operator=(double val)
{
if (is_leaf_node())
{
simple_val_.dval = val;
type_ = VAL_TYPE_FLOAT;
}
return *this;
}
gb_json& gb_json::operator=(const char* val)
{
if (is_leaf_node())
{
strval_ = val ? val : "";
type_ = VAL_TYPE_STRING;
}
return *this;
}

113
sdk/json/gb_json.h Normal file
View File

@ -0,0 +1,113 @@
#pragma once
#include <vector>
#include <string>
#include <mutex>
struct cJSON;
class gb_json
{
volatile int32_t ref_;
std::mutex ref_mutex_;
enum val_type
{
VAL_TYPE_NULL = 0,
VAL_TYPE_BOOL,
VAL_TYPE_INT,
VAL_TYPE_FLOAT,
VAL_TYPE_STRING,
VAL_TYPE_OBJECT,
VAL_TYPE_ARRAY,
};
val_type type_;
std::string key_;
union
{
bool bval;
int nval;
double dval;
}simple_val_;
std::string strval_;
std::vector<gb_json*> arr_val_;
size_t cur_child_;
static std::string object_key(gb_json* jsn);
static std::string array_key(gb_json* jsn);
void from_cjson(cJSON* cj);
gb_json* find_child(const char* key, bool remove = false);
public:
gb_json(char* json_txt = 0);
protected:
gb_json(const char* key, bool val);
gb_json(const char* key, int val);
gb_json(const char* key, double val);
gb_json(const char* key, const char* val);
~gb_json();
public:
int32_t add_ref();
int32_t release();
public:
// parse/un-parse ...
bool attach_text(char* json_txt);
void clear(bool as_array = false);
std::string to_string(void);
// attributes ...
std::string& key(void);
bool is_array(void);
bool is_leaf_node(void); // whether this object is a leaf node contains final value
// value access ...
bool get_value(const char* key, bool& val);
bool get_value(const char* key, int& val);
bool get_value(const char* key, double& val);
bool get_value(const char* key, std::string& val);
bool get_value(const char* key, gb_json*& val);
// enumeration ...
size_t children(void); // return children count if was object or array, or else -1 returned
gb_json* child(size_t ind);
gb_json* first_child(void);
gb_json* next_child(void);
// change the item matching 'key', otherwise add a new item
bool set_value(const char* key, bool val);
bool set_value(const char* key, int val);
bool set_value(const char* key, double val);
bool set_value(const char* key, const char* val);
bool set_value(const char* key, gb_json* val);
// operator+= only for array
gb_json& operator+=(bool val);
gb_json& operator+=(int val);
gb_json& operator+=(double val);
gb_json& operator+=(const char* val);
gb_json& operator+=(gb_json* val);
// remove item
gb_json& operator-=(int ind);
bool remove(const char* key);
bool remove(gb_json* child);
bool remove(int ind);
// position management
int index(gb_json* child);
int index_move_to(gb_json* child, int ind);
// leaf node value ...
bool value(bool& val);
bool value(int& val);
bool value(double& val);
bool value(std::string& val);
gb_json& operator=(bool val);
gb_json& operator=(int val);
gb_json& operator=(double val);
gb_json& operator=(const char* val);
};

View File

@ -40,35 +40,6 @@ namespace win_util
return ret;
}
HMODULE load_dll(const char* path_dll, int flag, int* err)
{
HMODULE h = LoadLibraryA(path_dll);
int ret = GetLastError();
utils::to_log(1, "[TWAIN]Load: LoadLibraryA(%s) = %d\r\n", path_dll, ret);
if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT))
{
std::string dir(path_dll);
size_t pos = dir.rfind('\\');
char path[MAX_PATH] = { 0 };
GetDllDirectoryA(_countof(path) - 1, path);
if (pos != std::wstring::npos)
dir.erase(pos);
utils::to_log(LOG_LEVEL_FATAL, "[TWAIN]Load: change directory to '%s' and retry LoadLibraryA(%s) ...\r\n", dir.c_str(), path_dll);
SetDllDirectoryA(dir.c_str());
h = LoadLibraryA(path_dll);
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
ret = GetLastError();
utils::to_log(1, "[TWAIN]Load: trying LoadLibraryA(%s) = %d, restore directory to '%s'\r\n", path_dll, ret, path);
SetDllDirectoryA(path);
}
if (err)
*err = ret;
return h;
}
};
#else
#include <dlfcn.h>
@ -128,15 +99,16 @@ void sane_helper::clear(void)
bool sane_helper::load_sane(const char* vendor) // libsane_hgsane.so.1, and vendor is 'hgsane'
{
bool ok = true;
clear();
#if OS_WIN
std::string file(dll_root_ + "sane.dll"), func("sane_");
#else
std::string file(dll_root_ + "libsane-" + vendor + ".so.1"), func("sane_");
#endif
bool ok = true;
clear();
dll_handle_ = LOAD_LIB(file.c_str(), LOAD_WITH_ALTERED_SEARCH_PATH);
dll_handle_ = utils::load_dll(file.c_str(), LOAD_WITH_ALTERED_SEARCH_PATH);
if(!dll_handle_)
{
utils::to_log(7, "load sane library(%s) = %s\n", file.c_str(), strerror(errno));

View File

@ -1,5 +1,7 @@
#include "scanned_img.h"
#include "sane_helper.h"
#include "../../sdk/hginclude/utils.h"
#include <string.h>
@ -14,7 +16,7 @@ namespace local_trans
int load_lang_pak(const char* dll)
{
HMODULE h = LOAD_LIB(dll, LOAD_WITH_ALTERED_SEARCH_PATH);
HMODULE h = utils::load_dll(dll, LOAD_WITH_ALTERED_SEARCH_PATH);
if(!h)
return GetLastError();

View File

@ -280,7 +280,7 @@ namespace callback
FreeLibrary(hui);
// hui = LoadLibraryExA(root.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
hui = LOAD_LIB(root.c_str(), LOAD_WITH_ALTERED_SEARCH_PATH);
hui = utils::load_dll(root.c_str(), LOAD_WITH_ALTERED_SEARCH_PATH);
if (!hui)
{
std::string info("Load '" + root);