diff --git a/hgsane/CMakeLists.txt b/hgsane/CMakeLists.txt
index 2957940..e0fb275 100644
--- a/hgsane/CMakeLists.txt
+++ b/hgsane/CMakeLists.txt
@@ -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
)
diff --git a/hgsane/entry.cpp b/hgsane/entry.cpp
new file mode 100644
index 0000000..6a6521c
--- /dev/null
+++ b/hgsane/entry.cpp
@@ -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
+
+///
+/// SANE API entrance ...
+///
+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;
+ }
+}
+
+
diff --git a/hgsane/json.cpp b/hgsane/json.cpp
deleted file mode 100644
index ce981e9..0000000
--- a/hgsane/json.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-
-#include "json.h"
-#include
-#include
-
-#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& 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;
-}
diff --git a/hgsane/json.h b/hgsane/json.h
deleted file mode 100644
index 958ab50..0000000
--- a/hgsane/json.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#if defined(WIN32) || defined(_WIN64)
-#include
-#endif
-
-#include "cJSON.h"
-#include
-#include
-
-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& 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);
-
-};
diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp
index bc69122..67a0405 100644
--- a/hgsane/sane_hg_mdw.cpp
+++ b/hgsane/sane_hg_mdw.cpp
@@ -1,6 +1,7 @@
#include "sane_hg_mdw.h"
-#include "json.h"
+#include "../sdk/json/gb_json.h"
+
#include
#include
#include
@@ -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 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 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 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 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 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;
// 关联?
- 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::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* 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::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::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& master)
+bool hg_sane_middleware::parse_depends(scanner_handle h, gb_json* jsn, SLAVEOP& so, std::vector& 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::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 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::iterator hg_sane_middleware::find_openning_device_in_que
return openning_.end();
}
-///
-
-///
-/// 导出接口
-///
-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
diff --git a/hgsane/sane_hg_mdw.h b/hgsane/sane_hg_mdw.h
index 62cd506..9f0cf1d 100644
--- a/hgsane/sane_hg_mdw.h
+++ b/hgsane/sane_hg_mdw.h
@@ -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& 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 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& master);
+ bool parse_depends(scanner_handle h, gb_json* jsn, SLAVEOP& so, std::vector& 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& 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& 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:
diff --git a/hgsane/sane_option.cpp b/hgsane/sane_option.cpp
index 69b2e20..4e9e289 100644
--- a/hgsane/sane_option.cpp
+++ b/hgsane/sane_option.cpp
@@ -3,6 +3,7 @@
#include
#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)
diff --git a/hgsane/sane_option.h b/hgsane/sane_option.h
index 354a42a..b8dd913 100644
--- a/hgsane/sane_option.h
+++ b/hgsane/sane_option.h
@@ -14,25 +14,15 @@
#endif
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "sane/sane_ex.h"
-#include "json.h"
#include
namespace local_utility
{
void* acquire_memory(size_t bytes, const char* info);
void free_memory(void* m);
-
- template
- void to_log(int level, const char* fmt, Args ... args)
- {
- size_t size = snprintf(nullptr, 0, fmt, args ...) + 2;
- std::unique_ptr 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:
diff --git a/sdk/hginclude/utils.cpp b/sdk/hginclude/utils.cpp
index a43323b..849d349 100644
--- a/sdk/hginclude/utils.cpp
+++ b/sdk/hginclude/utils.cpp
@@ -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);
diff --git a/sdk/hginclude/utils.h b/sdk/hginclude/utils.h
index d1d3abf..69b823d 100644
--- a/sdk/hginclude/utils.h
+++ b/sdk/hginclude/utils.h
@@ -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
+ 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 buf(new char[size]);
+
+ snprintf(buf.get(), size, fmt, args ...);
+ log_api(buf.get(), (log_level)level);
+ }
+ }
};
#if OS_WIN
diff --git a/hgsane/cJSON.c b/sdk/json/cJSON.c
similarity index 97%
rename from hgsane/cJSON.c
rename to sdk/json/cJSON.c
index cd60134..594376b 100644
--- a/hgsane/cJSON.c
+++ b/sdk/json/cJSON.c
@@ -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. */
}
diff --git a/hgsane/cJSON.h b/sdk/json/cJSON.h
similarity index 99%
rename from hgsane/cJSON.h
rename to sdk/json/cJSON.h
index 913bc1e..9fdbf9b 100644
--- a/hgsane/cJSON.h
+++ b/sdk/json/cJSON.h
@@ -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);
diff --git a/sdk/json/gb_json.cpp b/sdk/json/gb_json.cpp
new file mode 100644
index 0000000..ea7ec94
--- /dev/null
+++ b/sdk/json/gb_json.cpp
@@ -0,0 +1,817 @@
+
+#include "gb_json.h"
+#include "cJSON.h"
+#include
+#include
+
+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 lock(ref_mutex_);
+ int32_t ref = ++ref_;
+
+ return ref;
+}
+int32_t gb_json::release()
+{
+ int32_t ref = 0;
+
+ {
+ std::lock_guard 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;
+}
diff --git a/sdk/json/gb_json.h b/sdk/json/gb_json.h
new file mode 100644
index 0000000..f86dca9
--- /dev/null
+++ b/sdk/json/gb_json.h
@@ -0,0 +1,113 @@
+#pragma once
+
+#include
+#include
+#include
+
+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 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);
+};
diff --git a/twain/ds/sane_helper.cpp b/twain/ds/sane_helper.cpp
index 8301e9f..9261d1b 100644
--- a/twain/ds/sane_helper.cpp
+++ b/twain/ds/sane_helper.cpp
@@ -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
@@ -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));
diff --git a/twain/ds/scanned_img.cpp b/twain/ds/scanned_img.cpp
index bf254af..50824c4 100644
--- a/twain/ds/scanned_img.cpp
+++ b/twain/ds/scanned_img.cpp
@@ -1,5 +1,7 @@
#include "scanned_img.h"
+
#include "sane_helper.h"
+#include "../../sdk/hginclude/utils.h"
#include
@@ -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();
diff --git a/twain/ds/scanner.cpp b/twain/ds/scanner.cpp
index 5beb382..e22e663 100644
--- a/twain/ds/scanner.cpp
+++ b/twain/ds/scanner.cpp
@@ -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);