修复文件映射内存使用问题,补充win平台功能
This commit is contained in:
parent
1539a698b1
commit
5943ee86d6
|
@ -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();
|
||||
{
|
||||
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
|
||||
{
|
||||
size_ = size;
|
||||
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
|
||||
{
|
||||
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;
|
||||
*err = SCANNER_ERR_OUT_OF_RANGE;
|
||||
}
|
||||
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
|
||||
tiny_file_map::sys_unmap_api(buf_, size_);
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -601,6 +648,8 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha
|
|||
memset(buf_, 0, size_);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (tmp_path && *tmp_path)
|
||||
{
|
||||
std::string f(tmp_path);
|
||||
char buf[128] = { 0 };
|
||||
|
@ -610,20 +659,31 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha
|
|||
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
|
||||
f += buf;
|
||||
|
||||
unsigned int bytes = size_;
|
||||
fmap_.open(f.c_str(), size_, false);
|
||||
buf_ = fmap_.mapping_buffer();
|
||||
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,10 +743,21 @@ 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())
|
||||
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);
|
||||
|
@ -692,7 +765,6 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1020,7 +1020,17 @@ 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);
|
||||
unsigned int size = r;
|
||||
void* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = size;
|
||||
ret = io_->read_bulk(buff, &r);
|
||||
|
||||
while (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
|
@ -1029,7 +1039,17 @@ int hg_scanner_239::read_one_image_from_usb(void)
|
|||
break;
|
||||
|
||||
r = total - off;
|
||||
ret = io_->read_bulk(buf->data() + off, &r);
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue