修复文件映射内存使用问题,补充win平台功能

This commit is contained in:
gb 2022-06-06 12:03:24 +08:00
parent 1539a698b1
commit 5943ee86d6
10 changed files with 426 additions and 212 deletions

View File

@ -346,141 +346,183 @@ int shared_memory::write(const char* data, size_t len)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tiny_file_map ...
#ifdef WIN32
#define IS_VALID_MAP(map) map
#else
#define IS_VALID_MAP(map) map != -1
#endif
tiny_file_map::tiny_file_map() : size_(0), map_(0), buf_(nullptr), file_(""), keep_f_(false)
tiny_file_map::tiny_file_map() : size_(0), map_(INVALID_HANDLE_NAME), buf_(nullptr), file_(""), keep_f_(false)
, map_off_(0), map_bytes_(0), page_size_(hg_log::get_page_size())
{}
tiny_file_map::~tiny_file_map()
{
close();
}
int tiny_file_map::open(const char* file, unsigned int size, bool readonly)
HANDLE_NAME tiny_file_map::open_file_for_mapping(const char* file, unsigned* bytes, bool create)
{
close();
HANDLE_NAME ret = INVALID_HANDLE_NAME;
int ret = 0;
#ifdef WIN32
if (readonly)
HANDLE f = INVALID_HANDLE_VALUE;
if (create)
{
HANDLE f = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f != INVALID_HANDLE_VALUE)
{
size_ = GetFileSize(f, NULL);
map_ = CreateFileMappingA(f, NULL, PAGE_READONLY, 0, 0, NULL);
if (map_)
DWORD wrote = SetFilePointer(f, *bytes - 1, NULL, FILE_BEGIN);
if (wrote != *bytes - 1 || !WriteFile(f, "\0", 1, &wrote, NULL))
{
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0);
if (!buf_)
{
ret = GetLastError();
CloseHandle(map_);
map_ = nullptr;
size_ = 0;
}
CloseHandle(f);
f = INVALID_HANDLE_VALUE;
}
else
ret = GetLastError();
CloseHandle(f);
}
}
else
{
size_ = size;
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (f != INVALID_HANDLE_VALUE)
*bytes = GetFileSize(f, NULL);
}
if (f != INVALID_HANDLE_VALUE)
{
ret = CreateFileMapping(f, NULL, PAGE_READWRITE, 0, *bytes, NULL);
CloseHandle(f);
}
#else
if (create)
{
ret = ::open(file, O_CREAT | O_RDWR);
if (ret != INVALID_HANDLE_NAME)
{
if (lseek(ret, *bytes - 1, SEEK_SET) < 0)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", *bytes, errno);
::close(ret);
remove(file);
ret = INVALID_HANDLE_NAME;
}
if (write(ret, "0", 1) < 0)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", *bytes, errno);
::close(ret);
remove(file);
ret = INVALID_HANDLE_NAME;
}
}
}
else
{
ret = ::open(file, O_RDWR);
if (ret != INVALID_HANDLE_NAME)
{
struct stat fsize;
if (fstat(ret, &fsize) >= 0)
*bytes = fsize.st_size;
}
}
#endif
HANDLE f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
ret = GetLastError();
return ret;
}
void tiny_file_map::close_handle_name(HANDLE_NAME h)
{
#ifdef WIN32
CloseHandle(h);
#else
::close(h);
#endif
}
void* tiny_file_map::sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err)
{
void* mem = nullptr;
#ifdef WIN32
mem = MapViewOfFile(h, access, 0, off, size);
if (err)
{
if (mem)
*err = SCANNER_ERR_OK;
else
{
//SYSTEM_INFO si = { 0 };
//GetSystemInfo(&si);
//size += si.dwPageSize - 1;
//size /= si.dwPageSize;
//size *= si.dwPageSize;
DWORD wrote = SetFilePointer(f, size - 1, NULL, FILE_BEGIN);
if (wrote == size - 1)
WriteFile(f, "\0", 1, &wrote, NULL);
map_ = CreateFileMappingA(f, NULL, PAGE_READWRITE, 0, size, NULL);
if (map_)
{
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size);
if (!buf_)
ret = GetLastError();
}
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY)
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
else
ret = GetLastError();
CloseHandle(f);
if (ret)
{
keep_f_ = false;
close();
}
*err = SCANNER_ERR_OUT_OF_RANGE;
}
}
#else
if (readonly)
mem = mmap(nullptr, size, access, MAP_SHARED, h, off);
if (mem == MAP_FAILED)
{
map_ = ::open(file, O_RDONLY);
if (IS_VALID_MAP(map_))
{
struct stat fsize;
if (fstat(map_, &fsize) >= 0)
size_ = size = fsize.st_size;
}
mem = nullptr;
if (errno == ENOMEM)
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
else
*err = SCANNER_ERR_OUT_OF_RANGE;
}
else
{
map_ = ::open(file, O_CREAT | O_RDWR);
if (IS_VALID_MAP(map_))
{
if (lseek(map_, size - 1, SEEK_SET) < 0)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", size, errno);
ret = errno;
::close(map_);
map_ = 0;
remove(file);
return ret;
}
if (write(map_, "0", 1) < 0)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", size, errno);
ret = errno;
::close(map_);
map_ = 0;
remove(file);
return ret;
}
}
}
if (IS_VALID_MAP(map_))
{
buf_ = (unsigned char*)mmap(nullptr, size, readonly ? PROT_READ : PROT_WRITE, MAP_SHARED, map_, 0);
if (buf_ == (unsigned char*)MAP_FAILED)
{
buf_ = nullptr;
ret = errno;
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "mmap(%u) = %d\n", size, ret);
size_ = 0;
if (!readonly)
remove(file);
}
::close(map_);
map_ = 0;
}
else
ret = errno;
else if(err)
*err = SCANNER_ERR_OK;
#endif
return mem;
}
void tiny_file_map::sys_unmap_api(void* buf, size_t size)
{
#ifdef WIN32
UnmapViewOfFile(buf);
#else
munmap(buf, size);
#endif
}
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", readonly ? "R" : "RW", file, ret);
if (ret == 0)
int tiny_file_map::map_to_mem(unsigned int off)
{
int err = SCANNER_ERR_OUT_OF_RANGE;
#ifdef WIN32
int acc = FILE_MAP_READ | FILE_MAP_WRITE;
#else
int acc = PROT_READ | PROT_WRITE;
#endif
if (off < size_)
{
unsigned int bytes = size_ - off;
if (off >= map_off_ && off + bytes <= map_off_ + map_bytes_)
err = SCANNER_ERR_OK;
else
{
if (buf_)
tiny_file_map::sys_unmap_api(buf_, map_bytes_);
off /= page_size_;
off *= page_size_;
map_bytes_ = bytes;
map_off_ = off;
buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err); // MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, off, map_bytes_);
if (err != SCANNER_ERR_OK)
{
map_bytes_ /= page_size_;
map_bytes_ *= page_size_;
while (map_bytes_ >= page_size_
&& !(buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err))
&& err == SCANNER_ERR_INSUFFICIENT_MEMORY)
map_bytes_ -= page_size_;
}
}
}
return err;
}
int tiny_file_map::open(const char* file, bool existing, unsigned int size)
{
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
close();
map_ = tiny_file_map::open_file_for_mapping(file, &size, !existing);
if (map_ != INVALID_HANDLE_NAME)
{
ret = SCANNER_ERR_OK;
size_ = size;
}
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", existing ? "existing" : "new", file, ret);
if (ret == SCANNER_ERR_OK)
file_ = file;
return ret;
@ -489,21 +531,13 @@ void tiny_file_map::close(void)
{
if (buf_)
{
#ifdef WIN32
UnmapViewOfFile(buf_);
#else
munmap(buf_, size_);
#endif
tiny_file_map::sys_unmap_api(buf_, size_);
buf_ = nullptr;
}
if (map_)
if (map_ != INVALID_HANDLE_NAME)
{
#ifdef WIN32
CloseHandle(map_);
#else
::close(map_);
#endif
map_ = 0;
close_handle_name(map_);
map_ = INVALID_HANDLE_NAME;
}
if (!keep_f_ && !file_.empty())
remove(file_.c_str());
@ -511,14 +545,51 @@ void tiny_file_map::close(void)
size_ = 0;
file_ = "";
keep_f_ = false;
map_off_ = map_bytes_ = 0;
}
void tiny_file_map::keep_file(bool keep)
{
keep_f_ = keep;
}
unsigned char* tiny_file_map::mapping_buffer(void)
unsigned char* tiny_file_map::mapping_buffer(unsigned int off, unsigned int* bytes)
{
return buf_;
unsigned int len = bytes ? *bytes : size_;
unsigned char* buf = nullptr;
if (off >= size_)
{
return buf;
}
if (!buf_ && map_to_mem(off) != SCANNER_ERR_OK)
{
return buf;
}
if (off >= map_off_ && off + len <= map_off_ + map_bytes_)
{
buf = buf_ + off - map_off_;
return buf;
}
if (off < map_off_ || off >= map_off_ + map_bytes_)
{
if (map_to_mem(off) == SCANNER_ERR_OK)
{
buf = buf_ + off - map_off_;
if (bytes)
*bytes = map_bytes_ - (off - map_off_);
}
return buf;
}
//
buf = buf_ + off - map_off_;
if (bytes)
*bytes = map_bytes_ - (off - map_off_);
return buf;
}
std::string tiny_file_map::file(void)
{
@ -533,34 +604,8 @@ bool tiny_file_map::swap(void)
{
bool ret = true;
if (buf_)
{
#ifdef WIN32
UnmapViewOfFile(buf_);
#else
munmap(buf_, size_);
#endif
buf_ = nullptr;
}
else if (IS_VALID_MAP(map_))
{
#ifdef WIN32
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, size_);
#else
buf_ = (unsigned char*)mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, map_, 0);
if (buf_ == (unsigned char*)MAP_FAILED)
{
buf_ == nullptr;
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' failed: %d\n", file_.c_str(), errno);
}
#endif
ret = buf_ != nullptr;
}
else
{
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' bug the handle is %d\n", file_.c_str(), map_);
ret = false;
}
tiny_file_map::sys_unmap_api(buf_, size_);
buf_ = nullptr;
return ret;
}
@ -576,11 +621,13 @@ tiny_buffer::tiny_buffer(unsigned int size
{
init(tmp_path, name_leading, ext, uniq_id);
}
tiny_buffer::tiny_buffer(const char* src_file)
tiny_buffer::tiny_buffer(const char* src_file) : size_(0), buf_(nullptr)
{
fmap_.open(src_file, 0, true);
buf_ = fmap_.mapping_buffer();
fmap_.open(src_file);
size_ = fmap_.size();
unsigned int len = size_;
buf_ = fmap_.mapping_buffer(0, &len);
}
tiny_buffer::~tiny_buffer()
{
@ -602,28 +649,41 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha
}
catch (...)
{
std::string f(tmp_path);
char buf[128] = { 0 };
if (tmp_path && *tmp_path)
{
std::string f(tmp_path);
char buf[128] = { 0 };
f += PATH_SEPARATOR;
f += name_leading ? name_leading : "mapf";
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
f += buf;
f += PATH_SEPARATOR;
f += name_leading ? name_leading : "mapf";
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
f += buf;
fmap_.open(f.c_str(), size_, false);
buf_ = fmap_.mapping_buffer();
unsigned int bytes = size_;
fmap_.open(f.c_str(), size_, false);
buf_ = fmap_.mapping_buffer(0, &bytes);
}
}
// VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Acquire memory with bytes %u = %s\n", size_, hg_log::format_ptr(buf_).c_str());
}
unsigned int tiny_buffer::size(void)
{
return size_;
}
unsigned char* tiny_buffer::data(void)
unsigned char* tiny_buffer::data(unsigned int off, unsigned int* bytes)
{
return buf_;
if (off >= size_)
return nullptr;
if (fmap_.file().empty())
{
if (size_ - off < *bytes)
*bytes = size_ - off;
return buf_ + off;
}
return fmap_.mapping_buffer(off, bytes);
}
void tiny_buffer::keep_file(bool keep)
{
@ -640,8 +700,9 @@ bool tiny_buffer::swap(void)
return true;
bool ret = fmap_.swap();
unsigned int bytes = size_;
buf_ = fmap_.mapping_buffer();
buf_ = fmap_.mapping_buffer(0, &bytes);
return ret;
}
@ -672,6 +733,7 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
{
IMGDT imgd;
bool ret = false;
unsigned int l = bytes, off = 0;
imgd.header.bits = bpp;
imgd.header.bytes = bytes;
@ -681,18 +743,28 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
imgd.header.width = w;
imgd.offset = 0;
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
if(imgd.data->data())
unsigned char* buf = imgd.data->data(off, &l),
* src = (unsigned char*)data;
while(buf)
{
memcpy(imgd.data->data(), data, bytes);
if (imgd.data->swap())
{
std::lock_guard<std::mutex> lck(lock_);
queue_.push_back(imgd);
ret = true;
}
else
imgd.data.reset();
memcpy(buf, src, l);
off += l;
if (off >= bytes)
break;
src += l;
l = bytes - off;
buf = imgd.data->data(off, &l);
}
if (off >= bytes && imgd.data->swap())
{
std::lock_guard<std::mutex> lck(lock_);
queue_.push_back(imgd);
ret = true;
}
else
imgd.data.reset();
return ret;
}
@ -719,24 +791,29 @@ void final_img_queue::fetch_front(void* buf, int* len, bool* over)
}
else
{
// for third-apps, we make fake data upto len when re-map file failed here
IMGDT& imgd = queue_[0];
if (imgd.offset == 0)
{
if (!imgd.data->swap())
{
*len = 0;
if (over)
*over = true;
VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload final image '%s' failed!\n", imgd.data->file().c_str());
return;
}
}
if (imgd.offset + *len >= imgd.header.bytes)
*len = imgd.header.bytes - imgd.offset;
memcpy(buf, imgd.data->data() + imgd.offset, *len);
unsigned char* src = imgd.data->data(imgd.offset, (unsigned int*)len);
if (src)
{
memcpy(buf, src, *len);
}
else
{
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap final image '%s + 0x%08x' failed!\n", imgd.data->file().c_str(), imgd.offset);
}
imgd.offset += *len;
if (imgd.offset >= imgd.header.bytes)
{

View File

@ -131,27 +131,40 @@ public:
};
// buffer
#ifdef WIN32
#define HANDLE_NAME HANDLE
#define INVALID_HANDLE_NAME NULL
#else
#define HANDLE_NAME int
#define INVALID_HANDLE_NAME -1
#endif
class tiny_file_map
{
unsigned int size_;
#ifdef WIN32
HANDLE map_;
#else
int map_;
#endif
unsigned int page_size_;
HANDLE_NAME map_;
unsigned char *buf_;
std::string file_;
bool keep_f_;
unsigned int map_off_;
unsigned int map_bytes_;
int map_to_mem(unsigned int off = 0);
public:
tiny_file_map();
~tiny_file_map();
static HANDLE_NAME open_file_for_mapping(const char* file, unsigned* bytes, bool create);
static void close_handle_name(HANDLE_NAME h);
static void* sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err);
static void sys_unmap_api(void* buf, size_t size = 0);
public:
int open(const char* file, unsigned int size, bool readonly);
int open(const char* file, bool existing = true, unsigned int size = 0);
void close(void);
void keep_file(bool keep);
unsigned char* mapping_buffer(void);
unsigned char* mapping_buffer(unsigned int off, unsigned int* bytes);
std::string file(void);
unsigned int size(void);
@ -173,7 +186,7 @@ public:
public:
unsigned int size(void);
unsigned char* data(void);
unsigned char* data(unsigned int off, unsigned int* bytes/*[in] - need bytes, [out] - real bytes*/);
void keep_file(bool keep);
std::string file(void);

View File

@ -95,11 +95,17 @@ hg_scanner::hg_scanner(ScannerSerial serial
{
final_path_ = hg_log::ini_get("paths", "final_img");
if(final_path_.empty())
final_path_ = hg_log::get_scanner_path() + "imgs";
final_path_ = hg_log::local_data_path() + PATH_SEPARATOR + "imgs";
if (hg_log::create_folder(final_path_.c_str()))
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "temporary image folder: %s\n", final_path_.c_str());
final_path_ += PATH_SEPARATOR;
}
else
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "create temporary image folder failed: %s\n", final_path_.c_str());
final_path_ = "";
}
custom_gamma_val_ = new SANE_Gamma;
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
@ -1694,7 +1700,7 @@ std::shared_ptr<tiny_buffer> hg_scanner::aquire_memory(int size, bool from_usb)
unsigned int ind = from_usb ? usb_img_index_ : final_img_index_;
std::shared_ptr<tiny_buffer> mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind));
if (!mem->data())
if (!mem->data(0, (unsigned int*)&size))
{
mem.reset();
LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n");

View File

@ -573,7 +573,16 @@ int hg_scanner_200::get_img_data(unsigned int bytes)
if (total < block)
block = total;
ret = io_->read_bulk(imagedata->data() + index, &block);
unsigned int size = block;
void* buf = imagedata->data(index, &size);
if (!buf)
{
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
block = size;
ret = io_->read_bulk(buf, &block);
io_->set_timeout(500); //不能删除可能会导致IO超时
if (ret != SCANNER_ERR_OK)
break;

View File

@ -1020,16 +1020,36 @@ int hg_scanner_239::read_one_image_from_usb(void)
{
std::lock_guard<std::mutex> lock(io_lock_);
ret = io_->read_bulk(buf->data(), &r);
while (ret == SCANNER_ERR_OK)
unsigned int size = r;
void* buff = buf->data(off, &size);
if (!buff)
{
off += r;
if (off >= total)
break;
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
}
else
{
r = size;
ret = io_->read_bulk(buff, &r);
r = total - off;
ret = io_->read_bulk(buf->data() + off, &r);
while (ret == SCANNER_ERR_OK)
{
off += r;
if (off >= total)
break;
r = total - off;
size = r;
buff = buf->data(off, &size);
if (!buff)
{
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
r = size;
ret = io_->read_bulk(buff, &r);
}
}
}
if (ret == SCANNER_ERR_OK)
@ -1179,6 +1199,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode)
{
dev_conf_.g200params.color = 1;
}
HGSCANCONF d = dev_conf_;
if (image_prc_param_.bits.rid_color != RID_COLOR_NONE
@ -1203,6 +1224,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode)
}
if(color_mode == -1)
ret = writedown_device_configuration(&d);
return ret;
}
int hg_scanner_239::on_paper_changed(int& paper)

View File

@ -516,7 +516,16 @@ int hg_scanner_300::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
if (total < block)
block = total;
ret = io_->read_bulk(imagedata->data() + index,&block);
unsigned int size = block;
void* buf = imagedata->data(index, &size);
if (!buf)
{
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
block = size;
ret = io_->read_bulk(buf, &block);
if (ret != SCANNER_ERR_OK)
{

View File

@ -516,7 +516,16 @@ int hg_scanner_400::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
if (total < block)
block = total;
ret = io_->read_bulk(imagedata->data() + index,&block);
unsigned int size = block;
void* buf = imagedata->data(index, &size);
if (!buf)
{
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
block = size;
ret = io_->read_bulk(buf, &block);
if (ret != SCANNER_ERR_OK)
{

View File

@ -87,11 +87,31 @@ namespace hg_imgproc
public:
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
{
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
buffer_.reset(new std::vector<char>(buff->size()));
if (buffer_.get())
memcpy(buffer_->data(), buff->data(), buff->size());
{
unsigned int total = buff->size(),
off = 0, size = total;
unsigned char* mem = buff->data(off, &size);
while (mem)
{
memcpy(buffer_->data(), mem, size);
off += size;
if (off >= total)
{
ret = SCANNER_ERR_OK;
break;
}
size = total - off;
mem = buff->data(off, &size);
}
}
mats_.clear();
return SCANNER_ERR_OK;
return ret;
}
int load_file(const char* path_file)
{

View File

@ -445,9 +445,27 @@ extern "C"
{
return g_scanner_path;
}
unsigned int get_page_size(void)
{
unsigned int ps = 1024;
#ifdef WIN32
SYSTEM_INFO si = { 0 };
GetSystemInfo(&si);
ps = si.dwPageSize;
#else
ps = sysconf(_SC_PAGESIZE);
if(ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB
ps = getpagesize();
#endif
if (ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB
ps = 1024;
return ps;
}
static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path)
{
std::string me(self_path + PATH_SEPARATOR + "configs" + PATH_SEPARATOR + " scanner.conf");
std::string me(self_path + PATH_SEPARATOR + "Cfg" + PATH_SEPARATOR + " scanner.conf");
int lv = LOG_LEVEL_ALL;
hg_log_type tp = LOG_TYPE_FILE;
@ -477,31 +495,60 @@ extern "C"
else if (val == "fatal")
lv = LOG_LEVEL_FATAL;
}
else
create_folder((self_path + PATH_SEPARATOR + "Cfg").c_str());
return lv;
}
std::string local_data_path(void)
{
#ifdef WIN32
char* tmp = getenv("TMP");
std::string home(tmp ? tmp : "");
if (home.length())
{
size_t pos = home.rfind('\\');
if (pos++ != std::string::npos)
home.erase(pos);
}
#else
std::string home(getenv("HOME"));
home += "/.";
#endif
#ifdef OEM_HANWANG
home += "HwScanner";
#elif defined(OEM_LISICHENG)
home += "LscScanner";
#else
home += "HuaGoScan";
#endif;
create_folder(home.c_str());
return home;
}
int init(void)
{
char* file = nullptr;
std::string path("");
hg_log_type type = LOG_TYPE_FILE;
int level = get_log_config(get_scanner_path(), &type, &path);
int level = get_log_config(local_data_path(), &type, &path);
if (type == LOG_TYPE_FILE)
{
std::string name(""),
paths[] = {pe_path(&name), get_scanner_path(), simple_ini::temporary_path()};
paths[] = { local_data_path(), pe_path(&name), get_scanner_path(), simple_ini::temporary_path()};
int ind = 0;
if (path.empty() || !create_folder(path.c_str()))
path = paths[ind++];
else
if (!path.empty() && create_folder(path.c_str()))
ind = sizeof(paths) / sizeof(paths[0]) + 2;
for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind)
{
path = paths[ind] + PATH_SEPARATOR + "log";
path = paths[ind] + PATH_SEPARATOR + "Log";
if (create_folder(path.c_str()))
break;
}

View File

@ -49,6 +49,8 @@ extern "C"
std::string pe_path(std::string* name = nullptr);
std::string get_module_full_path(const char* module_part_name);
std::string get_scanner_path(void);
std::string local_data_path(void);
unsigned int get_page_size(void);
unsigned long long available_memory(void);
void str_tolower(std::string& str);
bool create_folder(const char* fodler);