Option_Descriptor采用二级指针,成员变化时只调整二级指针的内容,以保证一级指针不变
This commit is contained in:
parent
fe530a6c8a
commit
e6eaefb511
|
@ -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<std::string>& 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; // 硬件可设置默认<E9BB98>?
|
||||
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<int>& 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<double>& 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<DEVOPT> 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)
|
||||
{
|
||||
for (auto& v : dev->opts)
|
||||
hg_sane_middleware::free_descriptor(v.desc);
|
||||
|
||||
if (del)
|
||||
{
|
||||
if (dev->std_opt)
|
||||
delete dev->std_opt;
|
||||
for (auto& v : dev->opts)
|
||||
local_utility::free_memory(v.desc);
|
||||
|
||||
if(del)
|
||||
delete dev;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dev->std_opt)
|
||||
dev->std_opt->clear();
|
||||
dev->opts.clear();
|
||||
dev->cur_vals.clear();
|
||||
dev->slaves.clear();
|
||||
|
|
|
@ -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<std::string>& values);
|
||||
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue