#include "hg_scanner.h" #include "scanner_manager.h" #include #include #include #include "./scanner/scanner_handler.h" #include "user-opt/user.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // img_receiver img_receiver::img_receiver(LPPACKIMAGE head, size_t info_size, size_t size, std::function complete_routine, uint32_t id) : id_(id), head_(*head), info_size_(info_size) , size_(size), finish_(complete_routine) { buf_ = (uint8_t*)malloc(size); if (buf_) memset(buf_, 0, size); } img_receiver::~img_receiver() { if (buf_) free(buf_); buf_ = nullptr; } int img_receiver::put_data(const void* data, uint32_t* size) { size_t info = 0; if (info_.length() < info_size_) { size_t need = info_size_ - info_.length(); if (need > *size) { info = *size; info_ += std::string((const char*)data, *size); *size = 0; } else { info_ += std::string((const char*)data, need); *size -= need; info = need; } } if (*size) { if (*size > size_ - wpos_) *size = size_ - wpos_; memcpy(buf_ + wpos_, data, *size); wpos_ += *size; if (wpos_ >= size_ && finish_) finish_(this); } *size += info; return 0; } bool img_receiver::is_complete(void) { return wpos_ >= size_; } uint32_t img_receiver::get_required(void) { if (wpos_ >= size_) return 0; else return size_ - wpos_ + (info_size_ - info_.length()); } uint32_t img_receiver::id(void) { return id_; } size_t img_receiver::size(void) { return wpos_; } uint8_t* img_receiver::data(void) { return buf_; } std::string img_receiver::information(void) { return info_; } PACKIMAGE img_receiver::head(void) { return head_; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // hg_scanner hg_scanner::hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc, hguser* user, std::vector* constopts) : dev_(*dev), status_(SCANNER_ERR_OPENED_BY_OTHER_PROCESS) , msg_(from_default_language("\350\256\276\345\244\207\345\267\262\347\273\217\350\242\253\350\277\233\347\250\213 '%s' \345\215\240\347\224\250")) { singleton_ = hg_scanner::create_device_singleton(dev_.vid, dev_.pid, dev_.addr); if (!singleton_->is_first()) { std::string pre(singleton_->read()); size_t pos = msg_.find("%s"); if (pos == std::string::npos) msg_ += ": " + pre; else msg_.replace(pos, 2, pre); singleton_->release(); } else { set_where(dev->display_name.c_str()); user_ = user; init(); if (status() == SCANNER_ERR_OK) { imgproc_ = imgproc; imgproc_->add_ref(); dev_opts_->add(imgproc_); if (constopts) { for(auto& v: *constopts) dev_opts_->add(v); } imgpr_thread_.reset(new std::thread(&hg_scanner::thread_image_processor, this)); } } } hg_scanner::~hg_scanner() { close(); } shared_memory* hg_scanner::create_device_singleton(int vid, int pid, int addr) { unsigned long long key = vid; key <<= 16; key |= pid; key <<= 16; key |= addr; return new shared_memory(key); } void hg_scanner::init(void) { auto on_status = [this](uint32_t statu) ->void { //status_ = statu; }; auto on_image_received = [this](LPPACKIMAGE pimg, uint64_t size) ->data_holder_ptr { data_holder_ptr pdh = nullptr; return pdh; }; auto privilege = [this](int priv) -> bool { return user_->has_privilege(priv); }; auto privilege_empty = [this](int priv) -> bool { return true; }; auto logmsg = [&](const char* msg) -> void { utils::to_log(LOG_LEVEL_DEBUG, msg); }; scanner_ = new scanner_handler(); scanner_->set_image_receiver(on_image_received); scanner_->set_status_notifyer(on_status); std::string opts(""); int ret = scanner_->option_get_all(opts); if (ret == SCANNER_ERR_OK) { set_opt_json_text(&opts[0]); if(user_) dev_opts_ = new device_option(privilege, logmsg); else dev_opts_ = new device_option(privilege_empty, logmsg); dev_opts_->add(this); } else { status_ = ret; } } void hg_scanner::thread_image_processor(void) { imgproc_mgr * processor = imgproc_; img_receiver* raw = nullptr; processor->add_ref(); while (raw_imgs_.take(raw, true)) { } processor->release(); } int hg_scanner::start(void) { int ret = SCANNER_ERR_OK; cancelled_ = false; if (scanner_) ret = scanner_->scan_start(); return ret; } int hg_scanner::stop(void) { int ret = SCANNER_ERR_OK; cancelled_ = true; if (scanner_) ret = scanner_->scan_stop(); return ret; } int hg_scanner::close(void) { int ret = SCANNER_ERR_OK; if (scanner_) { ret = scanner_->close(); if (ret) return ret; scanner_->release(); scanner_ = nullptr; } if (dev_opts_) { dev_opts_->clear(); dev_opts_->release(); dev_opts_ = nullptr; } if (singleton_) { singleton_->release(); singleton_ = nullptr; } // wait image thread ... if (imgpr_thread_.get() && imgpr_thread_->joinable()) imgpr_thread_->join(); if (imgproc_) { imgproc_->release(); imgproc_ = nullptr; } user_ = nullptr; return ret; } int hg_scanner::re_connect(void) { return SCANNER_ERR_OK; } int hg_scanner::get_image_info(SANE_Parameters* pii) { return SCANNER_ERR_OK; } int hg_scanner::read_image_data(uint8_t* buf, size_t* len) { return SCANNER_ERR_OK; } int hg_scanner::status(void) { return status_; } std::string hg_scanner::status_message(void) { return msg_; } bool hg_scanner::is_online(void) { return online_; } device_option* hg_scanner::get_device_opt(void) { dev_opts_->add_ref(); return dev_opts_; }