From e6eaefb511fef4550d12c0a718c0fb6e9c6c66ce Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Mon, 19 Jun 2023 18:40:05 +0800 Subject: [PATCH] =?UTF-8?q?=20Option=5FDescriptor=E9=87=87=E7=94=A8?= =?UTF-8?q?=E4=BA=8C=E7=BA=A7=E6=8C=87=E9=92=88=EF=BC=8C=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=8F=98=E5=8C=96=E6=97=B6=E5=8F=AA=E8=B0=83=E6=95=B4=E4=BA=8C?= =?UTF-8?q?=E7=BA=A7=E6=8C=87=E9=92=88=E7=9A=84=E5=86=85=E5=AE=B9=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E4=BF=9D=E8=AF=81=E4=B8=80=E7=BA=A7=E6=8C=87=E9=92=88?= =?UTF-8?q?=E4=B8=8D=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hgsane/sane_hg_mdw.cpp | 229 ++++++++++++++++++----------------------- hgsane/sane_hg_mdw.h | 2 + hgsane/sane_option.cpp | 8 ++ hgsane/sane_option.h | 1 + 4 files changed, 112 insertions(+), 128 deletions(-) diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp index 8047ed6..a1c79d6 100644 --- a/hgsane/sane_hg_mdw.cpp +++ b/hgsane/sane_hg_mdw.cpp @@ -708,37 +708,54 @@ SANE_Handle hg_sane_middleware::scanner_handle_to_sane(scanner_handle h) return (SANE_Handle)(v); } +SANE_Option_Descriptor* hg_sane_middleware::allocate_descriptor(const char* name, const char* title, const char* desc) +{ + SANE_Option_Descriptor* opdesc = (SANE_Option_Descriptor*)local_utility::acquire_memory(sizeof(SANE_Option_Descriptor), "SANE_Option_Descriptor"); + + memset(opdesc, 0, sizeof(SANE_Option_Descriptor)); + + opdesc->name = (char*)local_utility::acquire_memory(strlen(name) + 1, "SANE_Option_Descriptor::name"); + strcpy((char*)opdesc->name, name); + + opdesc->title = (char*)local_utility::acquire_memory(strlen(title) + 1, "SANE_Option_Descriptor::title"); + strcpy((char*)opdesc->title, title); + + opdesc->desc = (char*)local_utility::acquire_memory(strlen(desc) + 1, "SANE_Option_Descriptor::desc"); + strcpy((char*)opdesc->desc, desc); + + return opdesc; +} +void hg_sane_middleware::free_descriptor(SANE_Option_Descriptor* desc) +{ + if (desc) + { + if (desc->name) + local_utility::free_memory((void*)desc->name); + desc->name = nullptr; + + if (desc->title) + local_utility::free_memory((void*)desc->title); + desc->title = nullptr; + + if (desc->desc) + local_utility::free_memory((void*)desc->desc); + desc->desc = nullptr; + + if (desc->constraint.range) + local_utility::free_memory((void*)desc->constraint.range); + desc->constraint.range = nullptr; + + local_utility::free_memory(desc); + } +} SANE_Option_Descriptor* hg_sane_middleware::string_option_to_SANE_descriptor(const char* name, const char* title, const char* desc , const std::vector& values) { - int bytes = sizeof(SANE_Option_Descriptor) + sizeof(char*); - SANE_Option_Descriptor *sod = NULL; - char *str = NULL, **str_arr = NULL; + int bytes = (values.size() + 1) * sizeof(SANE_String); + SANE_Option_Descriptor *sod = hg_sane_middleware::allocate_descriptor(name, title, desc); - bytes += ALIGN_INT(strlen(name) + 1); - bytes += ALIGN_INT(strlen(title) + 1); - bytes += ALIGN_INT(strlen(desc) + 1); - bytes += sizeof(SANE_Option_Descriptor); - bytes += sizeof(char*); for (size_t i = 0; i < values.size(); ++i) bytes += ALIGN_INT(values[i].length() + 1); - bytes += sizeof(char*) * (values.size() + 1); - sod = (SANE_Option_Descriptor*)local_utility::acquire_memory(bytes, "hg_sane_middleware::string_option_to_SANE_descriptor"); - bzero(sod, bytes); - str = (char*)sod; - str += sizeof(SANE_Option_Descriptor); - - sod->name = str; - strcpy(str, name); - str += ALIGN_INT(strlen(str) + 1); - - sod->title = str; - strcpy(str, title); - str += ALIGN_INT(strlen(str) + 1); - - sod->desc = str; - strcpy(str, desc); - str += ALIGN_INT(strlen(str) + 1); sod->type = SANE_TYPE_STRING; sod->unit = SANE_UNIT_NONE; @@ -747,51 +764,27 @@ SANE_Option_Descriptor* hg_sane_middleware::string_option_to_SANE_descriptor(con | SANE_CAP_AUTOMATIC; // 硬件可设置默认�? if (values.size()) { + SANE_String* buf = (SANE_String*)local_utility::acquire_memory(bytes, "string_list"); + char* str = (char*)buf + (values.size() + 1) * sizeof(SANE_String); + sod->constraint_type = SANE_CONSTRAINT_STRING_LIST; - sod->constraint.string_list = (char**)str; - str_arr = (char**)str; - str += (values.size() + 1) * sizeof(char*); + sod->constraint.string_list = buf; for (size_t i = 0; i < values.size(); ++i) { - str_arr[i] = str; + buf[i] = str; strcpy(str, values[i].c_str()); str += ALIGN_INT(values[i].length() + 1); } } - //VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes); - return sod; } SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc , bool double_val, double* lower, double* upper, double* step) { int bytes = sizeof(SANE_Option_Descriptor) + sizeof(SANE_Range); - SANE_Option_Descriptor *sod = NULL; - char *str = NULL; - - bytes += ALIGN_INT(strlen(name) + 1); - bytes += ALIGN_INT(strlen(title) + 1); - bytes += ALIGN_INT(strlen(desc) + 1); - bytes += sizeof(SANE_Option_Descriptor); - bytes += sizeof(SANE_Range*) + sizeof(SANE_Range); - sod = (SANE_Option_Descriptor*)local_utility::acquire_memory(bytes, "hg_sane_middleware::number_option_to_SANE_descriptor"); - bzero(sod, bytes); - str = (char*)sod; - str += sizeof(SANE_Option_Descriptor); - - sod->name = str; - strcpy(str, name); - str += ALIGN_INT(strlen(str) + 1); - - sod->title = str; - strcpy(str, title); - str += ALIGN_INT(strlen(str) + 1); - - sod->desc = str; - strcpy(str, desc); - str += ALIGN_INT(strlen(str) + 1); + SANE_Option_Descriptor *sod = hg_sane_middleware::allocate_descriptor(name, title, desc); sod->type = double_val ? SANE_TYPE_FIXED : SANE_TYPE_INT; sod->unit = SANE_UNIT_NONE; @@ -802,33 +795,33 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con { sod->size = sizeof(SANE_Range); sod->constraint_type = SANE_CONSTRAINT_RANGE; - sod->constraint.range = (SANE_Range*)str; + + SANE_Range* range = (SANE_Range*)local_utility::acquire_memory(sizeof(SANE_Range), "constraint.range"); if (lower) { if (double_val) - (*(SANE_Range*)str).min = hg_sane_middleware::double_2_sane_fixed(*lower); + range->min = hg_sane_middleware::double_2_sane_fixed(*lower); else - (*(SANE_Range*)str).min = (SANE_Word)*lower; + range->min = (SANE_Word)*lower; } if (upper) { if (double_val) - (*(SANE_Range*)str).max = hg_sane_middleware::double_2_sane_fixed(*upper); + range->max = hg_sane_middleware::double_2_sane_fixed(*upper); else - (*(SANE_Range*)str).max = (SANE_Word)*upper; + range->max = (SANE_Word)*upper; } - (*(SANE_Range*)str).quant = 0; + range->quant = 0; if (step) { if(double_val) - (*(SANE_Range*)str).quant = hg_sane_middleware::double_2_sane_fixed(*step); + range->quant = hg_sane_middleware::double_2_sane_fixed(*step); else - (*(SANE_Range*)str).quant = (SANE_Word)(*step); + range->quant = (SANE_Word)(*step); } - str = (char*)((SANE_Range*)str + 1); + sod->constraint.range = range; } - //VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes); return sod; } @@ -836,30 +829,7 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con , const std::vector& values) { int bytes = sizeof(SANE_Option_Descriptor) + sizeof(SANE_Range); - SANE_Option_Descriptor* sod = NULL; - char* str = NULL; - - bytes += ALIGN_INT(strlen(name) + 1); - bytes += ALIGN_INT(strlen(title) + 1); - bytes += ALIGN_INT(strlen(desc) + 1); - bytes += sizeof(SANE_Option_Descriptor); - bytes += sizeof(SANE_Word*) + sizeof(SANE_Word) * (values.size() + 1); - sod = (SANE_Option_Descriptor*)local_utility::acquire_memory(bytes, "hg_sane_middleware::number_option_to_SANE_descriptor"); - bzero(sod, bytes); - str = (char*)sod; - str += sizeof(SANE_Option_Descriptor); - - sod->name = str; - strcpy(str, name); - str += ALIGN_INT(strlen(str) + 1); - - sod->title = str; - strcpy(str, title); - str += ALIGN_INT(strlen(str) + 1); - - sod->desc = str; - strcpy(str, desc); - str += ALIGN_INT(strlen(str) + 1); + SANE_Option_Descriptor* sod = hg_sane_middleware::allocate_descriptor(name, title, desc); sod->type = SANE_TYPE_INT; sod->unit = SANE_UNIT_NONE; @@ -869,14 +839,12 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con if (values.size()) { - SANE_Word *val = (SANE_Word*)str; - sod->constraint.word_list = val; + sod->constraint.word_list = (SANE_Word*)local_utility::acquire_memory(sizeof(SANE_Word) * (values.size() + 1), "word_list"); + SANE_Word* val = (SANE_Word*)sod->constraint.word_list; sod->constraint_type = SANE_CONSTRAINT_WORD_LIST; *val++ = values.size(); for (size_t i = 0; i < values.size(); ++i) val[i] = values[i]; - - str = (char*)(val + values.size()); } //VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes); @@ -886,30 +854,7 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con , const std::vector& values) { int bytes = sizeof(SANE_Option_Descriptor) + sizeof(SANE_Range); - SANE_Option_Descriptor* sod = NULL; - char* str = NULL; - - bytes += ALIGN_INT(strlen(name) + 1); - bytes += ALIGN_INT(strlen(title) + 1); - bytes += ALIGN_INT(strlen(desc) + 1); - bytes += sizeof(SANE_Option_Descriptor); - bytes += sizeof(SANE_Word*) + sizeof(SANE_Word) * (values.size() + 1); - sod = (SANE_Option_Descriptor*)local_utility::acquire_memory(bytes, "hg_sane_middleware::number_option_to_SANE_descriptor"); - bzero(sod, bytes); - str = (char*)sod; - str += sizeof(SANE_Option_Descriptor); - - sod->name = str; - strcpy(str, name); - str += ALIGN_INT(strlen(str) + 1); - - sod->title = str; - strcpy(str, title); - str += ALIGN_INT(strlen(str) + 1); - - sod->desc = str; - strcpy(str, desc); - str += ALIGN_INT(strlen(str) + 1); + SANE_Option_Descriptor* sod = hg_sane_middleware::allocate_descriptor(name, title, desc); sod->type = SANE_TYPE_FIXED; sod->unit = SANE_UNIT_NONE; @@ -919,16 +864,13 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con if (values.size()) { - SANE_Word* val = (SANE_Word*)str; - sod->constraint.word_list = val; + sod->constraint.word_list = (SANE_Word*)local_utility::acquire_memory(sizeof(SANE_Word) * (values.size() + 1), "word_list"); + SANE_Word* val = (SANE_Word*)sod->constraint.word_list; sod->constraint_type = SANE_CONSTRAINT_WORD_LIST; *val++ = values.size(); for (size_t i = 0; i < values.size(); ++i) val[i] = hg_sane_middleware::double_2_sane_fixed(values[i]); - - str = (char*)(val + values.size()); } - //VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes); return sod; } @@ -979,12 +921,39 @@ void hg_sane_middleware::reload_options(scanner_handle dev) if (dev && dev != v->dev) continue; - hg_sane_middleware::free_device_inst(v, false); - + std::vector opts(std::move(v->opts)); long count = 0; + + hg_sane_middleware::free_device_inst(v, false); hg_scanner_get_parameter(v->dev, nullptr, NULL, &count); for (long ind = 1; ind < count; ++ind) + { get_option_descriptor(hg_sane_middleware::scanner_handle_to_sane(v->dev), (void*)ind); + + int n = v->opts.size() - 1; + if (n >= 0) + { + for (int i = 0; i < opts.size(); ++i) + { + if (v->opts[n].opt_name == opts[i].opt_name) + { + local_utility::free_memory((void*)opts[i].desc->name); + local_utility::free_memory((void*)opts[i].desc->title); + local_utility::free_memory((void*)opts[i].desc->desc); + local_utility::free_memory((void*)opts[i].desc->constraint.range); + + *opts[i].desc = *v->opts[n].desc; + v->opts[n].desc->name = v->opts[n].desc->title = v->opts[n].desc->desc = nullptr; + v->opts[n].desc->constraint.range = nullptr; + hg_sane_middleware::free_descriptor(v->opts[n].desc); + v->opts[n].desc = opts[i].desc; + opts.erase(opts.begin() + i); + + break; + } + } + } + } } } SANE_Status hg_sane_middleware::open(SANE_String_Const devicename, SANE_Handle* handle, const char* name, const char* pwd, const char* method, char* rsc) @@ -1247,15 +1216,19 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st } void hg_sane_middleware::free_device_inst(LPDEVINST dev, bool del) { - if (dev->std_opt) - delete dev->std_opt; for (auto& v : dev->opts) - local_utility::free_memory(v.desc); + hg_sane_middleware::free_descriptor(v.desc); - if(del) + if (del) + { + if (dev->std_opt) + delete dev->std_opt; delete dev; + } else { + if (dev->std_opt) + dev->std_opt->clear(); dev->opts.clear(); dev->cur_vals.clear(); dev->slaves.clear(); diff --git a/hgsane/sane_hg_mdw.h b/hgsane/sane_hg_mdw.h index a95304a..afc60ac 100644 --- a/hgsane/sane_hg_mdw.h +++ b/hgsane/sane_hg_mdw.h @@ -204,6 +204,8 @@ public: static std::string option_value_2_string(SANE_Value_Type type, void* val); 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); + static void free_descriptor(SANE_Option_Descriptor* desc); static SANE_Option_Descriptor* string_option_to_SANE_descriptor(const char* name, const char* title, const char* desc , const std::vector& values); static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc diff --git a/hgsane/sane_option.cpp b/hgsane/sane_option.cpp index 15c0103..63fa251 100644 --- a/hgsane/sane_option.cpp +++ b/hgsane/sane_option.cpp @@ -313,6 +313,14 @@ SANE_Option_Descriptor* sane_std_opts::get_option(int option) { return get_known_option(option); } +void sane_std_opts::clear(void) +{ + for (auto& v : known_opts_) + { + delete[] v.known.desc; + } + known_opts_.clear(); +} bool sane_std_opts::is_known_option(int opt, SANE_Option_Descriptor** user) { diff --git a/hgsane/sane_option.h b/hgsane/sane_option.h index 436734d..9c275d6 100644 --- a/hgsane/sane_option.h +++ b/hgsane/sane_option.h @@ -56,6 +56,7 @@ public: public: void init_known_opt(int option, SANE_Option_Descriptor* desc); SANE_Option_Descriptor* get_option(int option); + void clear(void); bool is_known_option(int opt, SANE_Option_Descriptor** user = nullptr); void* get_default_value(scanner_handle h, int opt); // call local_utility::free_memory to free the returned buffer