diff --git a/hgdriver/hgdev/BlockingQueue.h b/hgdriver/hgdev/BlockingQueue.h index 13ea81f..013a687 100644 --- a/hgdriver/hgdev/BlockingQueue.h +++ b/hgdriver/hgdev/BlockingQueue.h @@ -111,232 +111,4 @@ public: } }; -#include -typedef struct _img_header -{ - int width; - int height; - int bits; - int channels; - int line_bytes; - unsigned bytes; -}IMH; -typedef struct _img -{ - IMH header; - unsigned offset; - bool is_file; // when this is true, then the 'data' stores the full path of the file - void* fptr; - std::shared_ptr> data; -}IMGDT; -class image_data -{ -private: - image_data(const image_data& rhs); - image_data& operator =(const image_data& rhs); - mutable std::mutex _mutex; - std::condition_variable _condvar; - deque _queue; - bool isShutDown; - IMGDT tRet; - -public: - image_data() - : _mutex() - , _condvar() - , _queue() - , isShutDown(false) - { - } - - ~image_data() - { - ShutDown(); - std::cout << "blocking queue release" << std::endl; - } - - void Clear() - { - lock_guard lock(_mutex); - _condvar.notify_all(); - _queue.clear(); - } - - void ShutDown() - { - isShutDown = true; - _condvar.notify_all(); - _queue.clear(); - } - - bool IsShutDown() - { - return isShutDown; - } - - void Put(const IMGDT task) - { - lock_guard lock(_mutex); - if (!isShutDown) - { - { - _queue.push_back(task); - } - _condvar.notify_all(); - } - - } - bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes) - { - IMGDT img; - img.header.width = w; - img.header.height = h; - img.header.bits = bpp; - img.header.channels = channels; - img.header.line_bytes = line_bytes; - img.offset = 0; - img.header.bytes = bytes; - img.data.reset(new std::vector(bytes)); - if (!img.data.get()) - return false; - - img.is_file = false; - img.fptr = nullptr; - memcpy(img.data->data(), data, bytes); - Put(img); - - return true; - } - bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, const char* file) - { - IMGDT img; - img.header.width = w; - img.header.height = h; - img.header.bits = bpp; - img.header.channels = channels; - img.header.line_bytes = line_bytes; - img.offset = 0; - img.header.bytes = bytes; - img.is_file = true; - img.fptr = nullptr; - img.data.reset(new std::vector(strlen(file) * 2)); - if (!img.data.get()) - return false; - strcpy((char*)&img.data->data()[0], file); - - FILE* dst = fopen(file, "rw+b"); - if (!dst) - return false; - fwrite(data, 1, bytes, dst); - fclose(dst); - img.fptr = fopen(file, "rb"); // open and keep it - if (!img.fptr) - { - remove(file); - return false; - } - - Put(img); - return true; - } - IMGDT Take() - { - unique_lock lock(_mutex); - if (_queue.size() <= 0) - _condvar.wait(lock); - - if (isShutDown || _queue.empty()) - { - return tRet; - } - - IMGDT front(_queue.front()); - _queue.pop_front(); - - return front; - } - - IMGDT Front() - { - unique_lock lock(_mutex); - if (_queue.size() <= 0) - _condvar.wait(lock); - - if (isShutDown || _queue.empty()) - { - return tRet; - } - - IMGDT front(_queue.front()); - return front; - } - bool front(IMH* header) - { - unique_lock lock(_mutex); - if (_queue.size() <= 0) - _condvar.wait(lock); - - if (isShutDown || _queue.empty()) - { - return false; - } - - memcpy(header, &_queue.front().header, sizeof(*header)); - - return true; - } - size_t Size() const - { - lock_guard lock(_mutex); - return _queue.size(); - } - - void fetch_front(void* buf, int* len, bool* over) - { - if (Size() == 0) - *len = 0; - else - { - lock_guard lock(_mutex); - if (_queue.front().is_file) - { - if (_queue.front().data->size() - _queue.front().offset <= *len) - { - *len = _queue.front().data->size() - _queue.front().offset; - fread(buf, 1, *len, (FILE*)_queue.front().fptr); - fclose((FILE*)_queue.front().fptr); - remove((const char*)_queue.front().data->data()); - _queue.pop_front(); - if (over) - *over = true; - } - else - { - fread(buf, 1, *len, (FILE*)_queue.front().fptr); - _queue.front().offset += *len; - if (over) - *over = false; - } - } - else - { - if (_queue.front().data->size() - _queue.front().offset <= *len) - { - *len = _queue.front().data->size() - _queue.front().offset; - memcpy(buf, _queue.front().data->data() + _queue.front().offset, *len); - _queue.pop_front(); - if (over) - *over = true; - } - else - { - memcpy(buf, _queue.front().data->data() + _queue.front().offset, *len); - _queue.front().offset += *len; - if (over) - *over = false; - } - } - } - } -}; #endif diff --git a/hgdriver/hgdev/hg_ipc.cpp b/hgdriver/hgdev/hg_ipc.cpp index c91d965..d02bb0d 100644 --- a/hgdriver/hgdev/hg_ipc.cpp +++ b/hgdriver/hgdev/hg_ipc.cpp @@ -7,6 +7,8 @@ #else #include #include +#include +#include #include #endif @@ -248,7 +250,7 @@ char* shared_memory::get_buf(void) #else int* h = (int*)&obj_; char* buf = (char*)shmat(*h, 0, 0); - VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shared memory %d buffer = %s, error = %d\n", *h, hg_log::format_ptr(buf).c_str(), errno); + VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shared memory %d tiny_buffer = %s, error = %d\n", *h, hg_log::format_ptr(buf).c_str(), errno); #endif return buf; @@ -340,3 +342,407 @@ int shared_memory::write(const char* data, size_t len) len_ = len; release_buf(buf); } + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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() +{ + close(); +} + +int tiny_file_map::open(const char* file, unsigned int size, bool readonly) +{ + close(); + + int ret = 0; +#ifdef WIN32 + if (readonly) + { + HANDLE f = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (f == INVALID_HANDLE_VALUE) + ret = GetLastError(); + else + { + size_ = GetFileSize(f, NULL); + map_ = CreateFileMappingA(f, NULL, PAGE_READONLY, 0, 0, NULL); + if (map_) + { + buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0); + if (!buf_) + { + ret = GetLastError(); + CloseHandle(map_); + map_ = nullptr; + size_ = 0; + } + } + else + ret = GetLastError(); + CloseHandle(f); + } + } + else + { + size_ = size; + + HANDLE f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (f == INVALID_HANDLE_VALUE) + ret = GetLastError(); + 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_READONLY, 0, size, NULL); + if (map_) + { + buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, size); + if (!buf_) + ret = GetLastError(); + } + else + ret = GetLastError(); + CloseHandle(f); + if (ret) + { + keep_f_ = false; + close(); + } + } + } +#else + if (readonly) + { + map_ = ::open(file, O_RDONLY); + if (IS_VALID_MAP(map_)) + { + struct stat fsize; + if (fstat(map_, &fsize) >= 0) + size_ = size = fsize.st_size; + } + } + 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; +#endif + + + VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", readonly ? "R" : "RW", file, ret); + if (ret == 0) + file_ = file; + + return ret; +} +void tiny_file_map::close(void) +{ + if (buf_) + { +#ifdef WIN32 + UnmapViewOfFile(buf_); +#else + munmap(buf_, size_); +#endif + buf_ = nullptr; + } + if (map_) + { +#ifdef WIN32 + CloseHandle(map_); +#else + ::close(map_); +#endif + map_ = 0; + } + if (!keep_f_ && !file_.empty()) + remove(file_.c_str()); + + size_ = 0; + file_ = ""; + keep_f_ = false; +} +void tiny_file_map::keep_file(bool keep) +{ + keep_f_ = keep; +} +unsigned char* tiny_file_map::mapping_buffer(void) +{ + return buf_; +} +std::string tiny_file_map::file(void) +{ + return file_; +} +unsigned int tiny_file_map::size(void) +{ + return size_; +} + +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; + } + + return ret; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// memory or file mapping ... +tiny_buffer::tiny_buffer(unsigned int size + , const char* tmp_path + , const char* name_leading + , const char* ext + , unsigned int uniq_id) + : size_(size), buf_(nullptr) +{ + init(tmp_path, name_leading, ext, uniq_id); +} +tiny_buffer::tiny_buffer(const char* src_file) +{ + fmap_.open(src_file, 0, true); + buf_ = fmap_.mapping_buffer(); + size_ = fmap_.size(); +} +tiny_buffer::~tiny_buffer() +{ + if (buf_) + { + if (fmap_.file().empty()) + delete[] buf_; + else + fmap_.close(); + } +} + +void tiny_buffer::init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id) +{ + try + { + buf_ = new unsigned char[size_]; + memset(buf_, 0, size_); + } + catch (...) + { + 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; + + fmap_.open(f.c_str(), size_, false); + buf_ = fmap_.mapping_buffer(); + } + +// 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) +{ + return buf_; +} +void tiny_buffer::keep_file(bool keep) +{ + fmap_.keep_file(keep); +} +std::string tiny_buffer::file(void) +{ + return fmap_.file(); +} + +bool tiny_buffer::swap(void) +{ + if (fmap_.file().empty()) + return true; + + bool ret = fmap_.swap(); + + buf_ = fmap_.mapping_buffer(); + + return ret; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// final_img_queue + +final_img_queue::final_img_queue() +{} +final_img_queue::~final_img_queue() +{} + +size_t final_img_queue::size(void) +{ + std::lock_guard lck(lock_); + + return queue_.size(); +} +void final_img_queue::clear(void) +{ + std::lock_guard lck(lock_); + + queue_.clear(); +} +bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes + , const char* tmp_path, const char* name_leading, const char* ext, int ind) +{ + IMGDT imgd; + bool ret = false; + + imgd.header.bits = bpp; + imgd.header.bytes = bytes; + imgd.header.channels = channels; + imgd.header.height = h; + imgd.header.line_bytes = line_bytes; + imgd.header.width = w; + imgd.offset = 0; + imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind)); + if(imgd.data->data()) + { + memcpy(imgd.data->data(), data, bytes); + if (imgd.data->swap()) + { + std::lock_guard lck(lock_); + queue_.push_back(imgd); + ret = true; + } + else + imgd.data.reset(); + } + + return ret; +} +bool final_img_queue::front(IMH* header) +{ + std::lock_guard lck(lock_); + if (queue_.size() == 0) + return false; + + memcpy(header, &queue_[0].header, sizeof(*header)); + + return true; +} +void final_img_queue::fetch_front(void* buf, int* len, bool* over) +{ + std::lock_guard lck(lock_); + + if (queue_.size() == 0) + { + if(len) + *len = 0; + if(over) + *over = true; + } + else + { + 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); + imgd.offset += *len; + if (imgd.offset >= imgd.header.bytes) + { + if (over) + *over = true; + queue_.erase(queue_.begin()); + } + } +} diff --git a/hgdriver/hgdev/hg_ipc.h b/hgdriver/hgdev/hg_ipc.h index 4cae825..fcab959 100644 --- a/hgdriver/hgdev/hg_ipc.h +++ b/hgdriver/hgdev/hg_ipc.h @@ -14,11 +14,14 @@ #include #include #include +#include #define USB_TIMEOUT_INFINITE 0 #endif #include +#include #include +#include class platform_event @@ -125,4 +128,88 @@ public: bool is_first(void); std::string read(void); int write(const char* data, size_t len); +}; + +// buffer +class tiny_file_map +{ + unsigned int size_; +#ifdef WIN32 + HANDLE map_; +#else + int map_; +#endif + unsigned char *buf_; + std::string file_; + bool keep_f_; + +public: + tiny_file_map(); + ~tiny_file_map(); + +public: + int open(const char* file, unsigned int size, bool readonly); + void close(void); + void keep_file(bool keep); + unsigned char* mapping_buffer(void); + std::string file(void); + unsigned int size(void); + + // mapping if unmapped; or unmapping if mapped + bool swap(void); +}; +class tiny_buffer +{ + unsigned int size_; + unsigned char *buf_; + tiny_file_map fmap_; + + void init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id); + +public: + tiny_buffer(unsigned int size, const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id); + tiny_buffer(const char* src_file); + ~tiny_buffer(); + +public: + unsigned int size(void); + unsigned char* data(void); + void keep_file(bool keep); + std::string file(void); + + // mapping if unmapped; or unmapping if mapped + bool swap(void); +}; + +typedef struct _img_header +{ + int width; + int height; + int bits; + int channels; + int line_bytes; + unsigned bytes; +}IMH; +typedef struct _img +{ + IMH header; + unsigned offset; + std::shared_ptr data; +}IMGDT; +class final_img_queue +{ + mutable std::mutex lock_; + std::vector queue_; + +public: + final_img_queue(); + ~final_img_queue(); + +public: + size_t size(void); + void clear(void); + bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes + , const char* tmp_path, const char* name_leading, const char* ext, int ind); + bool front(IMH* header); + void fetch_front(void* buf, int* len, bool* over); }; \ No newline at end of file diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index 035a9f7..774e0e2 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -95,9 +95,9 @@ hg_scanner::hg_scanner(ScannerSerial serial { final_path_ = hg_log::ini_get("paths", "final_img"); if(final_path_.empty()) - final_path_ = g_module_path + "imgs"; + final_path_ = hg_log::get_scanner_path() + "imgs"; if (hg_log::create_folder(final_path_.c_str())) - final_path_ += "/"; + final_path_ += PATH_SEPARATOR; else final_path_ = ""; @@ -187,12 +187,12 @@ int hg_scanner::save_2_tempory_file(std::shared_ptr> data, std FILE* dst = nullptr; int ret = SCANNER_ERR_OK; - sprintf(head, "scan_%06u", index); - file = hg_scanner::temporary_file((char*)".jpg", (char*)head); - dst = fopen(file.c_str(), "wb+"); + sprintf(head, "usb_%05u", index); + if(!path_file || path_file->empty()) + file = hg_scanner::temporary_file((char*)".jpg", (char*)head); + dst = fopen(file.c_str(), "wb"); if (dst) { - ENOSPC; EROFS; strerror(errno); size_t wrote = fwrite(data->data(), 1, data->size(), dst); if (wrote == data->size()) { @@ -670,8 +670,8 @@ void hg_scanner::thread_handle_image_process(void) { while (run_ && !user_cancel_) { - std::shared_ptr> buffer; - if (imgs_.Size() == 0 && paths_.Size() == 0) + std::shared_ptr tiny_buffer; + if (imgs_.Size() == 0) { if (wait_usb_.is_waiting()) break; @@ -680,39 +680,13 @@ void hg_scanner::thread_handle_image_process(void) continue; } - if (is_to_file()) - { - std::string file(paths_.Take()); - FILE* src = fopen(file.c_str(), "rb+"); - if (src) - { - unsigned length = 0; - - fseek(src, 0, SEEK_END); - length = ftell(src); - fseek(src, 0, SEEK_SET); - buffer = aquire_memory((int)length, false); - if (!buffer.get()) - { - - status_ = SCANNER_ERR_INSUFFICIENT_MEMORY; - break; - } - fread(buffer->data(), 1, length, src); - fclose(src); - remove(file.c_str()); - } - else - { - VLOG_MINI_1(LOG_LEVEL_FATAL, "FATAL: open tempory image file '%s' failed.\n", file.c_str()); - } - } + tiny_buffer = imgs_.Take(); + if(tiny_buffer->swap()) + image_process(tiny_buffer); else { - buffer = imgs_.Take(); + VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload USB data '%s' failed!\n", tiny_buffer->file().c_str()); } - - image_process(buffer); } } @@ -720,16 +694,13 @@ void hg_scanner::working_begin(void*) { final_img_index_ = 0; notify_ui_working_status(STATU_DESC_SCAN_WORKING, SANE_EVENT_WORKING, SCANNER_ERR_OK); + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "[%s] scanning ...\n", hg_log::current_time().c_str()); } void hg_scanner::working_done(void*) { imgs_.Clear(); if(user_cancel_) - final_imgs_.Clear(); - while (paths_.Size()) - { - remove(paths_.Take().c_str()); - } + final_imgs_.clear(); switch (status_) { @@ -798,15 +769,13 @@ void hg_scanner::working_done(void*) break; } - //notify_ui_working_status(STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_); - if (test_1_paper_) { LOG_INFO(LOG_LEVEL_DEBUG_INFO, "scanning mode: finished testing ONE paper, restore to normal scanning.\n"); } else { - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "scanned %d picture(s) and finished with error %s.\n", final_img_index_, hg_scanner_err_name(status_)); + VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "[%s] scanned %d picture(s) and finished with error %s.\n", hg_log::current_time().c_str(), final_img_index_, hg_scanner_err_name(status_)); } test_1_paper_ = false; @@ -904,7 +873,7 @@ int hg_scanner::setting_help(void* data) #ifdef WIN32 com = ""; - helpfile.insert(0, g_module_path); + helpfile.insert(0, hg_log::get_scanner_path()); FILE* src = fopen(helpfile.c_str(), "rb"); if (src) fclose(src); @@ -1686,7 +1655,7 @@ int hg_scanner::try_third_app_handle_start(bool& handled) while (wait_usb_result_.try_wait()) std::this_thread::sleep_for(std::chrono::milliseconds(3)); - if (!wait_img_.is_waiting() || !wait_usb_.is_waiting() || final_imgs_.Size()) + if (!wait_img_.is_waiting() || !wait_usb_.is_waiting() || final_imgs_.size()) ret = SCANNER_ERR_OK; else if (final_img_index_) { @@ -1713,40 +1682,18 @@ int hg_scanner::try_third_app_after_start(int err) return err; } -std::shared_ptr> hg_scanner::aquire_memory(int size, bool from_usb) +std::shared_ptr hg_scanner::aquire_memory(int size, bool from_usb) { - std::shared_ptr> mem; + std::string lead(from_usb ? "usb" : "imgp"), ext(from_usb ? "jpg" : "dat"); + unsigned int ind = from_usb ? usb_img_index_ : final_img_index_; + std::shared_ptr mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind)); - try - { - mem.reset(new std::vector(size)); - } - catch (...) + if (!mem->data()) { mem.reset(); - VLOG_MINI_1(LOG_LEVEL_FATAL, "Allocate memory of bytes %u failed!\n", size); - } - - if (!mem.get()) - { - if (from_usb && final_imgs_.Size()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - try - { - mem.reset(new std::vector(size)); - } - catch (...) - { - mem.reset(); - VLOG_MINI_1(LOG_LEVEL_FATAL, "Allocate memory of bytes %u failed secondary after 10 milliseconds!\n", size); - } - } - if (!mem.get()) - { - LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n"); - stop(); - } + LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n"); + notify_ui_working_status(STATU_DESC_SCANNER_ERR_INSUFFICIENT_MEMORY, SANE_EVENT_ERROR, SCANNER_ERR_INSUFFICIENT_MEMORY); + stop(); } return mem; @@ -1824,30 +1771,22 @@ void hg_scanner::copy_to_sane_image_header(SANE_Parameters* header, int w, int h header->lines = h; header->bytes_per_line = line_bytes; } -int hg_scanner::save_usb_data(std::shared_ptr> data) +int hg_scanner::save_usb_data(std::shared_ptr data) { int ret = SCANNER_ERR_OK; usb_img_index_++; VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "USB read one picture with %u bytes\n", data->size()); - if (is_to_file()) + if (!data->swap()) { - std::string file(""); - - ret = hg_scanner::save_2_tempory_file(data, &file, usb_img_index_); - if (ret == SCANNER_ERR_OK) - paths_.Put(file); + ret = SCANNER_ERR_OPEN_FILE_FAILED; } else { imgs_.Put(data); - -#ifdef SAVE_TO_FILE - hg_scanner::save_2_tempory_file(data, NULL, usb_img_index_); -#endif + if (wait_img_.is_waiting()) + wait_img_.notify(); } - if (wait_img_.is_waiting()) - wait_img_.notify(); return ret; } @@ -1856,8 +1795,7 @@ int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf) std::string bw(""); final_img_index_++; - //if (image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE) - if(img_conf_.pixtype == 0) + if (image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE) { int old = head->line_bytes; bw = bmp_821((unsigned char*)buf, head->width, head->height, &head->line_bytes, async_io_); @@ -1877,25 +1815,11 @@ int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf) return ui_ev_cb_((scanner_handle)this, SANE_EVENT_IMAGE_OK, &img, &final_img_index_, NULL); } - if (resolution_ <= 300 && final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes)) + if (final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes + , final_path_.c_str(), "final", "dat", final_img_index_)) return SCANNER_ERR_OK; else - { - // try file ... - char name[40] = { 0 }; - - sprintf(name, "img_%05d.dat", final_img_index_); - if (resolution_ <= 300) - { - VLOG_MINI_2(LOG_LEVEL_WARNING, "Memory(%u bytes) allocating failed when save final image, try save to file: %s\n", head->total_bytes, (final_path_ + name).c_str()); - } - if(!final_path_.empty() && - final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes - , (final_path_ + name).c_str())) - return SCANNER_ERR_OK; - else - return SCANNER_ERR_INSUFFICIENT_MEMORY; - } + return SCANNER_ERR_INSUFFICIENT_MEMORY; } int hg_scanner::is_running(void) { @@ -2247,10 +2171,10 @@ int hg_scanner::get_image_info(SANE_Parameters* ii) bzero(&imh, sizeof(imh)); bzero(ii, sizeof(*ii)); - while ((!wait_img_.is_waiting() || !wait_usb_.is_waiting()) && final_imgs_.Size() <= 0) + while ((!wait_img_.is_waiting() || !wait_usb_.is_waiting()) && final_imgs_.size() <= 0) this_thread::sleep_for(chrono::milliseconds(10)); - if (final_imgs_.Size() <= 0) + if (final_imgs_.size() <= 0) ret = SCANNER_ERR_NO_DATA; else { @@ -2301,7 +2225,7 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len) return SCANNER_ERR_INSUFFICIENT_MEMORY; } - if (final_imgs_.Size() > 0) + if (final_imgs_.size() > 0) { int fetch = *len; bool over = false; diff --git a/hgdriver/hgdev/hg_scanner.h b/hgdriver/hgdev/hg_scanner.h index 2ced6a6..7dfc6f0 100644 --- a/hgdriver/hgdev/hg_scanner.h +++ b/hgdriver/hgdev/hg_scanner.h @@ -210,7 +210,7 @@ protected: virtual int set_setting_value(int setting_no, void* data, int len); virtual int on_scanner_closing(bool force); virtual void thread_handle_usb_read(void) = 0; - virtual void image_process(std::shared_ptr>& buff) = 0; + virtual void image_process(std::shared_ptr& buff) = 0; protected: volatile bool run_; @@ -251,25 +251,24 @@ protected: SCANCONF img_conf_; //此参数外部不做任何改变,请在writedown_image_configuration做修改 std::string img_type_; - image_data final_imgs_; // JPG ... + final_img_queue final_imgs_; // JPG ... unsigned int usb_img_index_; unsigned int final_img_index_; std::string final_path_; - BlockingQueue>> imgs_; - BlockingQueue paths_; + BlockingQueue> imgs_; void init_settings(const char* json_setting_text); int on_scann_error(int err); // 返回“0”忽略错误继续执行,其它值则停止后续工作 int try_third_app_handle_start(bool& handled); int try_third_app_after_start(int err); - std::shared_ptr> aquire_memory(int size, bool from_usb = true); + std::shared_ptr aquire_memory(int size, bool from_usb = true); // callback to ui ... int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = SCANNER_ERR_OK); bool waiting_for_memory_enough(unsigned need_bytes); void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels, int bits); - int save_usb_data(std::shared_ptr> data); + int save_usb_data(std::shared_ptr data); int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf); enum thread_running diff --git a/hgdriver/hgdev/hg_scanner_200.cpp b/hgdriver/hgdev/hg_scanner_200.cpp index 3051794..337bbe4 100644 --- a/hgdriver/hgdev/hg_scanner_200.cpp +++ b/hgdriver/hgdev/hg_scanner_200.cpp @@ -473,14 +473,14 @@ int hg_scanner_200::stop(void) user_cancel_ = true; if (ret == SCANNER_ERR_DEVICE_BUSY) { - LOG_INFO(LOG_LEVEL_DEBUG_INFO,"stop status is busy\r\n"); + LOG_INFO(LOG_LEVEL_DEBUG_INFO,"stop status is busy\r\n"); std::this_thread::sleep_for(std::chrono::milliseconds(2000)); } else if (ret == SCANNER_ERR_OK) { status_ = SCANNER_ERR_DEVICE_STOPPED; } - final_imgs_.Clear(); + final_imgs_.clear(); return status_; } @@ -550,7 +550,7 @@ int hg_scanner_200::get_img_data(unsigned int bytes) ret = SCANNER_ERR_OK, index = 0, block = total; - std::shared_ptr> imagedata(aquire_memory(total)); + std::shared_ptr imagedata(aquire_memory(total)); if (!imagedata.get()) return SCANNER_ERR_INSUFFICIENT_MEMORY; @@ -571,7 +571,7 @@ int hg_scanner_200::get_img_data(unsigned int bytes) if (total < block) block = total; - ret = io_->read_bulk(imagedata->data() + index,&block); + ret = io_->read_bulk(imagedata->data() + index, &block); io_->set_timeout(500); //不能删除可能会导致IO超时 if (ret != SCANNER_ERR_OK) break; @@ -587,7 +587,7 @@ int hg_scanner_200::get_img_data(unsigned int bytes) return ret; } -void hg_scanner_200::image_process(std::shared_ptr>& buffer) +void hg_scanner_200::image_process(std::shared_ptr& buffer) { int ret = SCANNER_ERR_OK; hg_imgproc::IMGPRCPARAM param; diff --git a/hgdriver/hgdev/hg_scanner_200.h b/hgdriver/hgdev/hg_scanner_200.h index 0072058..74833c9 100644 --- a/hgdriver/hgdev/hg_scanner_200.h +++ b/hgdriver/hgdev/hg_scanner_200.h @@ -26,7 +26,7 @@ class hg_scanner_200 : public hg_scanner protected: virtual int on_scanner_closing(bool force) override; virtual void thread_handle_usb_read(void) override; - virtual void image_process(std::shared_ptr>& buff) override; + virtual void image_process(std::shared_ptr& buff) override; virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx diff --git a/hgdriver/hgdev/hg_scanner_239.cpp b/hgdriver/hgdev/hg_scanner_239.cpp index 28c175e..abe5bf5 100644 --- a/hgdriver/hgdev/hg_scanner_239.cpp +++ b/hgdriver/hgdev/hg_scanner_239.cpp @@ -620,7 +620,7 @@ void hg_scanner_239::init_version(void) else is_kernelsnap_211209_ = false; } -void hg_scanner_239::image_process(std::shared_ptr>& buff) +void hg_scanner_239::image_process(std::shared_ptr& buff) { VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Process image with %u bytes content ...\n", buff->size()); @@ -1000,7 +1000,7 @@ int hg_scanner_239::read_one_image_from_usb(void) ret = status_; else { - std::shared_ptr> buf(aquire_memory(total)); + std::shared_ptr buf(aquire_memory(total)); if (!buf.get()) return SCANNER_ERR_INSUFFICIENT_MEMORY; @@ -1701,17 +1701,13 @@ int hg_scanner_239::stop(void) user_cancel_ = true; ret = write_command(SC_STOP); io_->set_timeout(500); - final_imgs_.Clear(); + final_imgs_.clear(); return status_; } int hg_scanner_239::reset(void) { - final_imgs_.Clear(); - - while (paths_.Size() > 0) - remove(paths_.Take().c_str()); - + final_imgs_.clear(); discard_all_images(); return status_; diff --git a/hgdriver/hgdev/hg_scanner_239.h b/hgdriver/hgdev/hg_scanner_239.h index c9bca91..c0fd3f6 100644 --- a/hgdriver/hgdev/hg_scanner_239.h +++ b/hgdriver/hgdev/hg_scanner_239.h @@ -72,7 +72,7 @@ protected: virtual void on_device_reconnected(void) override; virtual int on_scanner_closing(bool force) override; virtual void thread_handle_usb_read(void) override; - virtual void image_process(std::shared_ptr>& buff) override; + virtual void image_process(std::shared_ptr& buff) override; public: hg_scanner_239(const char* dev_name, int pid,usb_io* io); diff --git a/hgdriver/hgdev/hg_scanner_300.cpp b/hgdriver/hgdev/hg_scanner_300.cpp index 0499ff3..e868c97 100644 --- a/hgdriver/hgdev/hg_scanner_300.cpp +++ b/hgdriver/hgdev/hg_scanner_300.cpp @@ -322,7 +322,7 @@ void hg_scanner_300::thread_handle_usb_read(void) if (ret == SCANNER_ERR_OK && usb.u32_Count > 0) { int totalNum = usb.u32_Count; - std::shared_ptr> imagedata(aquire_memory(totalNum)); + std::shared_ptr imagedata(aquire_memory(totalNum)); if (!imagedata.get()) { @@ -425,7 +425,7 @@ int hg_scanner_300::stop(void) { status_ = SCANNER_ERR_DEVICE_STOPPED; } - final_imgs_.Clear(); + final_imgs_.clear(); return status_; } @@ -491,7 +491,7 @@ int hg_scanner_300::get_scanner_status(USBCB &usb) scanner_err code = settingsdsp_300::device_status_to_hg_err(usb.u32_Data); return code ; } -int hg_scanner_300::get_img_data(std::shared_ptr> &imagedata) +int hg_scanner_300::get_img_data(std::shared_ptr &imagedata) { int total = imagedata->size(), ret = SCANNER_ERR_OK, @@ -535,7 +535,7 @@ int hg_scanner_300::get_img_data(std::shared_ptr> &imagedata) return ret; } -void hg_scanner_300::image_process(std::shared_ptr>& buffer) +void hg_scanner_300::image_process(std::shared_ptr& buffer) { int ret = SCANNER_ERR_OK; hg_imgproc::IMGPRCPARAM param; diff --git a/hgdriver/hgdev/hg_scanner_300.h b/hgdriver/hgdev/hg_scanner_300.h index 5e3abd6..8b16ab4 100644 --- a/hgdriver/hgdev/hg_scanner_300.h +++ b/hgdriver/hgdev/hg_scanner_300.h @@ -25,7 +25,7 @@ class hg_scanner_300 : public hg_scanner protected: virtual int on_scanner_closing(bool force) override; virtual void thread_handle_usb_read(void) override; - virtual void image_process(std::shared_ptr>& buff) override; + virtual void image_process(std::shared_ptr& buff) override; virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx @@ -55,7 +55,7 @@ private: int readusb(USBCB &usb); int pop_image(void); int get_scanner_status(USBCB &usb); - int get_img_data(std::shared_ptr> &imagedata); + int get_img_data(std::shared_ptr &imagedata); int writedown_device_configuration(bool type =false,HGSCANCONF_G400 *d = NULL); void writedown_image_configuration(void); void printf_devconfig(HGSCANCONF_G400 *d = NULL); diff --git a/hgdriver/hgdev/hg_scanner_400.cpp b/hgdriver/hgdev/hg_scanner_400.cpp index f2da8ec..a9d828e 100644 --- a/hgdriver/hgdev/hg_scanner_400.cpp +++ b/hgdriver/hgdev/hg_scanner_400.cpp @@ -319,7 +319,7 @@ void hg_scanner_400::thread_handle_usb_read(void) if (ret == SCANNER_ERR_OK && usb.u32_Count > 0) { int totalNum = usb.u32_Count; - std::shared_ptr> imagedata(aquire_memory(totalNum)); + std::shared_ptr imagedata(aquire_memory(totalNum)); if (!imagedata.get()) { @@ -424,7 +424,7 @@ int hg_scanner_400::stop(void) VLOG_MINI_1(LOG_LEVEL_WARNING, "stop device:(%s)\n", hg_scanner_err_name(status_)); } notify_ui_working_status("取消扫描", SANE_EVENT_STATUS, status_); - final_imgs_.Clear(); + final_imgs_.clear(); return status_; } @@ -489,7 +489,7 @@ int hg_scanner_400::get_scanner_status(USBCB &usb) scanner_err code = settingsdsp_400::device_status_to_hg_err(usb.u32_Data); return code ; } -int hg_scanner_400::get_img_data(std::shared_ptr> &imagedata) +int hg_scanner_400::get_img_data(std::shared_ptr &imagedata) { int total = imagedata->size(), ret = SCANNER_ERR_OK, @@ -533,7 +533,7 @@ int hg_scanner_400::get_img_data(std::shared_ptr> &imagedata) return ret; } -void hg_scanner_400::image_process(std::shared_ptr>& buffer) +void hg_scanner_400::image_process(std::shared_ptr& buffer) { int ret = SCANNER_ERR_OK; hg_imgproc::IMGPRCPARAM param; diff --git a/hgdriver/hgdev/hg_scanner_400.h b/hgdriver/hgdev/hg_scanner_400.h index 92089c0..866ee0c 100644 --- a/hgdriver/hgdev/hg_scanner_400.h +++ b/hgdriver/hgdev/hg_scanner_400.h @@ -25,7 +25,7 @@ class hg_scanner_400 : public hg_scanner protected: virtual int on_scanner_closing(bool force) override; virtual void thread_handle_usb_read(void) override; - virtual void image_process(std::shared_ptr>& buff) override; + virtual void image_process(std::shared_ptr& buff) override; virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx @@ -54,7 +54,7 @@ private: int readusb(USBCB &usb); int pop_image(void); int get_scanner_status(USBCB &usb); - int get_img_data(std::shared_ptr> &imagedata); + int get_img_data(std::shared_ptr &imagedata); int writedown_device_configuration(bool type =false,HGSCANCONF_G400 *d = NULL); void writedown_image_configuration(void); void printf_devconfig(HGSCANCONF_G400 *d = NULL); diff --git a/hgdriver/hgdev/image_process.cpp b/hgdriver/hgdev/image_process.cpp index 84d9aca..8e7cf29 100644 --- a/hgdriver/hgdev/image_process.cpp +++ b/hgdriver/hgdev/image_process.cpp @@ -27,6 +27,7 @@ extern "C" #include "ocr/hanwangOCRdetect.h" } #endif +#include "hg_ipc.h" using namespace std; #define GET_BYTE(a) ((a) & 0x0ff) @@ -84,9 +85,11 @@ namespace hg_imgproc // load data public: - int load_raw_data(std::shared_ptr> buff) + int load_raw_data(std::shared_ptr buff) { - buffer_.reset(new std::vector(*buff)); + buffer_.reset(new std::vector(buff->size())); + if (buffer_.get()) + memcpy(buffer_->data(), buff->data(), buff->size()); mats_.clear(); return SCANNER_ERR_OK; } @@ -843,7 +846,7 @@ namespace hg_imgproc return (HIMGPRC)obj; } - int load_buffer(HIMGPRC himg, std::shared_ptr> buff) + int load_buffer(HIMGPRC himg, std::shared_ptr buff) { return ((imgproc*)himg)->load_raw_data(buff); } diff --git a/hgdriver/hgdev/image_process.h b/hgdriver/hgdev/image_process.h index 8606d1e..7b5faf4 100644 --- a/hgdriver/hgdev/image_process.h +++ b/hgdriver/hgdev/image_process.h @@ -8,7 +8,8 @@ #include "common_setting.h" #include #include -//#include "common_setting.h" + +class tiny_buffer; namespace hg_imgproc { typedef struct _img_data @@ -159,7 +160,7 @@ namespace hg_imgproc HIMGPRC init(LPSCANCONF parameter,LPIMGPRCPARAM param,int pid); - int load_buffer(HIMGPRC himg,std::shared_ptr> buff); + int load_buffer(HIMGPRC himg,std::shared_ptr buff); int load_file(HIMGPRC himg, const char* path_file); //图像数据转换 diff --git a/hgdriver/hgdev/usb_manager.cpp b/hgdriver/hgdev/usb_manager.cpp index 394f2c4..9ed5d14 100644 --- a/hgdriver/hgdev/usb_manager.cpp +++ b/hgdriver/hgdev/usb_manager.cpp @@ -652,28 +652,32 @@ bool usb_io::claim_interterface(usb_manager::USBSIMPLEX* spl) return true; } - VLOG_MINI_2(LOG_LEVEL_FATAL, " first libusb_claim_interface(%d) = %s\n", spl->iface, libusb_error_name(ret)); + VLOG_MINI_2(LOG_LEVEL_FATAL, "libusb_claim_interface(%d) = %s, now try some actions ...\n", spl->iface, libusb_error_name(ret)); ret = libusb_kernel_driver_active(handle_, spl->iface); if (ret == 1) { ret = libusb_detach_kernel_driver(handle_, spl->iface); - VLOG_MINI_2(LOG_LEVEL_FATAL, " libusb_detach_kernel_driver(%d) = %s\n", spl->iface, libusb_error_name(ret)); + VLOG_MINI_2(LOG_LEVEL_FATAL, " libusb_detach_kernel_driver(%d) = %s\n", spl->iface, libusb_error_name(ret)); } else if (ret == LIBUSB_ERROR_NO_DEVICE) { last_err_ = SCANNER_ERR_DEVICE_NOT_FOUND; - VLOG_MINI_1(LOG_LEVEL_FATAL, "device(%s) maybe left when libusb_kernel_driver_active.\n", hg_log::format_ptr(dev_info_.device).c_str()); + VLOG_MINI_1(LOG_LEVEL_FATAL, " device(%s) maybe left when libusb_kernel_driver_active.\n", hg_log::format_ptr(dev_info_.device).c_str()); return false; } - VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_clear_halt(%x) ...\n", spl->port); - libusb_clear_halt(handle_, spl->port); - VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_release_interface(%u) ...\n", spl->iface); - libusb_release_interface(handle_, spl->iface); - VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_set_configuration(%u) ...\n", spl->iconf); - libusb_set_configuration(handle_, spl->iconf); + else + { + VLOG_MINI_2(LOG_LEVEL_FATAL, " libusb_kernel_driver_active(%d) = %d\n", spl->iface, ret); + } + ret = libusb_clear_halt(handle_, spl->port); + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_clear_halt(%x) = %s\n", spl->port, libusb_error_name(ret)); + ret = libusb_release_interface(handle_, spl->iface); + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_release_interface(%u) = %s\n", spl->iface, libusb_error_name(ret)); + ret = libusb_set_configuration(handle_, spl->iconf); + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_set_configuration(%u) = %s\n", spl->iconf, libusb_error_name(ret)); //ret = libusb_reset_device(handle_); //VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_reset_device = %s\n", libusb_error_name(ret)); //if (ret == LIBUSB_ERROR_NOT_FOUND) @@ -689,6 +693,7 @@ bool usb_io::claim_interterface(usb_manager::USBSIMPLEX* spl) if (ret == LIBUSB_SUCCESS) { spl->claimed = true; + VLOG_MINI_2(LOG_LEVEL_FATAL, "second libusb_claim_interface(%d) = %s\n", spl->iface, libusb_error_name(ret)); return true; } diff --git a/hgdriver/wrapper/hg_log.cpp b/hgdriver/wrapper/hg_log.cpp index a6c4138..94fe077 100644 --- a/hgdriver/wrapper/hg_log.cpp +++ b/hgdriver/wrapper/hg_log.cpp @@ -34,6 +34,9 @@ #define _INTSIZEOF(n) ((sizeof(n) + sizeof(long) - 1) & ~(sizeof(long) - 1)) #endif + +extern std::string g_scanner_path; // Ending with '\\' + class log_cls { typedef void(*log_to)(const char*, void*); @@ -75,6 +78,7 @@ protected: } public: + static std::string g_time_tag; static log_cls* instance(void) { if (!log_cls::inst_) @@ -112,6 +116,9 @@ public: { unsigned char bom[] = { 0x0ef, 0x0bb, 0x0bf }; fwrite(bom, sizeof(bom), 1, file_); + + std::string now(g_time_tag + hg_log::current_time() + g_time_tag + " started.\n"); + fwrite(now.c_str(), 1, now.length(), file_); ret = 0; } } @@ -141,6 +148,7 @@ public: } }; log_cls* log_cls::inst_ = NULL; +std::string log_cls::g_time_tag = "====="; #ifdef EXPORT_AS_C extern "C" @@ -433,10 +441,13 @@ extern "C" return ff.found; } - + std::string get_scanner_path(void) + { + return g_scanner_path; + } static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path) { - std::string me(self_path + "/configs/scanner.conf"); + std::string me(self_path + PATH_SEPARATOR + "configs" + PATH_SEPARATOR + " scanner.conf"); int lv = LOG_LEVEL_ALL; hg_log_type tp = LOG_TYPE_FILE; @@ -473,35 +484,39 @@ extern "C" int init(void) { char* file = nullptr; - std::string me(g_module_path), path(""); + std::string path(""); hg_log_type type = LOG_TYPE_FILE; - int level = get_log_config(me, &type, &path); + int level = get_log_config(get_scanner_path(), &type, &path); if (type == LOG_TYPE_FILE) { - if (path.empty()) - path = me; - path += "/log"; - if (!create_folder(path.c_str())) + std::string name(""), + paths[] = {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 + ind = sizeof(paths) / sizeof(paths[0]) + 2; + + for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind) { - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Create log-folder '%s' failed(%d), now try temporary directory\n", path.c_str(), errno); - path = simple_ini::temporary_path() + "/log"; - if (!create_folder(path.c_str())) - { - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "create temporary directory '%s' failed(%d), log to console\n", path.c_str(), errno); - type = LOG_TYPE_CONSOLE; - } + path = paths[ind] + PATH_SEPARATOR + "log"; + if (create_folder(path.c_str())) + break; + } + if(ind == sizeof(paths) / sizeof(paths[0])) + { + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Try PE, scanner and temporary path failed(%d), log to console\n", errno); + type = LOG_TYPE_CONSOLE; } if (type == LOG_TYPE_FILE) { - std::string name(""); - - pe_path(&name); if (name.empty()) - path += "/scanner.log"; + path += std::string(PATH_SEPARATOR) + "scanner.log"; else - path += "/" + name + ".log"; + path += PATH_SEPARATOR + name + ".log"; file = &path[0]; VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Log to file: '%s'\n", path.c_str()); } @@ -510,6 +525,11 @@ extern "C" return log_cls::instance()->set_log_type(type, file); } + void unint(void) + { + std::string now(log_cls::g_time_tag + hg_log::current_time() + log_cls::g_time_tag + " exited.\n"); + log(now.c_str()); + } void log(int level, const char* info) { if (lcb_) diff --git a/hgdriver/wrapper/hg_log.h b/hgdriver/wrapper/hg_log.h index c82687a..565606b 100644 --- a/hgdriver/wrapper/hg_log.h +++ b/hgdriver/wrapper/hg_log.h @@ -10,6 +10,9 @@ #ifdef WIN32 #define bzero(a, l) memset(a, 0, l) +#define PATH_SEPARATOR "\\" +#else +#define PATH_SEPARATOR "/" #endif #ifdef OEM_HANWANG @@ -43,6 +46,7 @@ extern "C" std::string u2utf8(const wchar_t* u); 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); unsigned long long available_memory(void); void str_tolower(std::string& str); bool create_folder(const char* fodler); @@ -54,6 +58,7 @@ extern "C" // // Return: 0 - success, or -1 in LOG_TYPE_FILE and log_file cannot be created int init(void); + void unint(void); void log(int level, const char* info); bool is_log_level_enabled(int level); diff --git a/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp b/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp index c8cb960..d700ae8 100644 --- a/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp +++ b/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp @@ -3,6 +3,12 @@ #include "../hgdev/scanner_manager.h" #include +#ifdef WIN32 +#include +#else +#include +#include +#endif #ifndef VERSION_MAJOR #define VERSION_MAJOR 1 @@ -16,8 +22,9 @@ | (((unsigned long long)(b) & 0x0ffff) << 32) \ | (((unsigned long long)(c) & 0x0ffff) << 16) \ | (((unsigned long long)(d) & 0x0ffff) << 0)) +#define GET_BUILD_VER VERSION_BUILD - 100000 -std::string g_module_path = ""; +std::string g_scanner_path = ""; static std::string g_sane_name = ""; static std::string g_sane_ver = ""; @@ -25,16 +32,30 @@ extern "C" { scanner_err hg_scanner_initialize(sane_callback callback, void* reserve) { -#ifndef WIN32 - size_t pos = 0; - g_module_path = hg_log::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str()); - pos = g_module_path.rfind('/'); + std::string name(""), + pe(hg_log::pe_path(&name)), + path("\\"), + scanner(g_scanner_path), + sane(hg_log::get_module_full_path((g_sane_name + ".so").c_str())); +#ifdef WIN32 + size_t pos = g_scanner_path.rfind('\\'); if (pos++ != std::string::npos) - g_module_path.erase(pos); + g_scanner_path.erase(pos); +#else + size_t pos = 0; + g_scanner_path = hg_log::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str()); + scanner = g_scanner_path; + path = "/"; + pos = g_scanner_path.rfind('/'); + if (pos++ != std::string::npos) + g_scanner_path.erase(pos); #endif hg_log::init(); + VLOG_MINI_5(LOG_LEVEL_DEBUG_INFO, "Module device: [%u.%u.%u.%u] - %s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER, scanner.c_str()); + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Module sane : [%s] - %s\n", g_sane_ver.c_str(), sane.c_str()); + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Module exe : %s\n", (pe + path + name).c_str()); - hg_scanner_mgr::set_version(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, VERSION_BUILD - 100000); + hg_scanner_mgr::set_version(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER); hg_scanner_mgr::instance(callback); return SCANNER_ERR_OK; @@ -42,11 +63,12 @@ extern "C" void hg_scanner_uninitialize(void) { hg_scanner_mgr::clear(); + hg_log::unint(); } unsigned long long hg_scanner_get_version(void) { - return MAKE_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, VERSION_BUILD - 100000); + return MAKE_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER); } scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only) @@ -256,6 +278,54 @@ extern "C" return buf; } + + int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block) + { + int ret = SCANNER_ERR_OK; + +#ifdef WIN32 + ULARGE_INTEGER av = { 0 }, + all = { 0 }; + if (GetDiskFreeSpaceExA(path, &av, &all, NULL)) + { + if (total) + *total = all.QuadPart; + if (avail) + *avail = av.QuadPart; + if (block) + { + DWORD sec = 0, + clu = 0; + std::string root(path); + size_t pos = root.find(":\\"); + if (pos != std::string::npos) + root.erase(pos + 2); + if (GetDiskFreeSpaceA(root.c_str(), &clu, &sec, NULL, NULL)) + { + *block = clu * sec; + } + } + } + else + ret = GetLastError(); +#else + struct statfs fs = { 0 }; + + ret = statfs(path, &fs); + if (ret == 0) + { + VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, " Total: %lld, Free: %lld, Avail: %lld, block size: %lld\n", + fs.f_blocks, fs.f_bfree, fs.f_bavail, fs.f_bsize); + if (total) + *total = fs.f_blocks * fs.f_bsize; + if (avail) + *avail = fs.f_bavail * fs.f_bsize; + if (block) + *block = fs.f_bsize; + } +#endif + return ret; + } } @@ -265,15 +335,15 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) { - if (g_module_path.empty()) + if (g_scanner_path.empty()) { char path[MAX_PATH] = { 0 }; GetModuleFileNameA(inst, path, _countof(path) - 1); - if (strrchr(path, '\\')) + // if (strrchr(path, '\\')) { - strrchr(path, '\\')[1] = 0; - g_module_path = path; + // strrchr(path, '\\')[1] = 0; + g_scanner_path = path; } } } diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp index 474ecae..0c6b2eb 100644 --- a/hgsane/sane_hg_mdw.cpp +++ b/hgsane/sane_hg_mdw.cpp @@ -33,6 +33,8 @@ #define iconv_t void* #endif +static std::string g_sane_path = ""; + namespace local_utility { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -275,12 +277,6 @@ namespace local_utility { if (version_code) *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD); // leading-char '1' is used for avoid compiler considering '0118' as an octal number :) - - unsigned long long v = hg_scanner_get_version(); - unsigned short* w = (unsigned short*)&v; - - VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "scanner version: %u.%u.%u.%u\n", w[3], w[2], w[1], w[0]); - VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "%s version: %u.%u.%u\n", GET_BACKEND_NAME, SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD); } void stop_work(void) { @@ -310,10 +306,10 @@ hg_sane_middleware::hg_sane_middleware(void) : opt_0_(nullptr), std_opt_(nullptr char path[512] = { 0 }; size_t pos = 0; - g_module_path = get_file_path((std::string(GET_BACKEND_NAME) + ".so").c_str(), path); - pos = g_module_path.rfind('/'); + g_sane_path = get_file_path((std::string(GET_BACKEND_NAME) + ".so").c_str(), path); + pos = g_sane_path.rfind('/'); if (pos++ != std::string::npos) - g_module_path.erase(pos); + g_sane_path.erase(pos); #endif } hg_sane_middleware::~hg_sane_middleware() @@ -1962,13 +1958,11 @@ extern "C" { // avoid compiler exporting name in C++ style !!! #ifdef WIN32 -std::string g_module_path = ""; - BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) { - if (g_module_path.empty()) + if (g_sane_path.empty()) { char path[MAX_PATH] = { 0 }; @@ -1976,7 +1970,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) if (strrchr(path, '\\')) { strrchr(path, '\\')[1] = 0; - g_module_path = path; + g_sane_path = path; } } } diff --git a/sdk/hginclude/huagaoxxx_warraper_ex.h b/sdk/hginclude/huagaoxxx_warraper_ex.h index b1cfe5f..125276a 100644 --- a/sdk/hginclude/huagaoxxx_warraper_ex.h +++ b/sdk/hginclude/huagaoxxx_warraper_ex.h @@ -131,8 +131,6 @@ #define MAKE_STR(str) _TO_STR(str) #define GET_BACKEND_NAME MAKE_STR(BACKEND_NAME) -#include -extern std::string g_module_path; // Ending with '\\' typedef struct _device { @@ -433,6 +431,19 @@ extern "C"{ // Return: 返回buf char* get_file_path(const char* name, char* buf); + // Function: 获取磁盘空间 + // + // Parameters: path - 全路径 + // + // total - 总空间大小(字节) + // + // avail - 可用空间大小(字节) + // + // block - 磁盘单元(块/簇)大小(字节) + // + // Return: 0 - 成功;其它为失败代码 + int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block); + #ifdef __cplusplus } #endif