增加匹配压缩图像接收的功能
This commit is contained in:
parent
3ce1d9a368
commit
b1af6d0d4d
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ hg_scanner::hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc, hguser* user, std
|
||||||
{
|
{
|
||||||
thread_image_processor();
|
thread_image_processor();
|
||||||
};
|
};
|
||||||
imgpr_thread_.start(tf, "hg_scanner::thread_image_processor", NULL);
|
imgpr_thread_.start(tf, 0, "hg_scanner::thread_image_processor");
|
||||||
#else
|
#else
|
||||||
imgpr_thread_.reset(new std::thread(&hg_scanner::thread_image_processor, this));
|
imgpr_thread_.reset(new std::thread(&hg_scanner::thread_image_processor, this));
|
||||||
#endif
|
#endif
|
||||||
|
@ -258,10 +257,9 @@ void hg_scanner::thread_image_processor(void)
|
||||||
}
|
}
|
||||||
void hg_scanner::process_image(image_holder_ptr img)
|
void hg_scanner::process_image(image_holder_ptr img)
|
||||||
{
|
{
|
||||||
PACKIMAGE h;
|
bool addref = true;
|
||||||
|
|
||||||
h.prc_stage = -1;
|
if (!dump_path_.empty())
|
||||||
if (!dump_path_.empty() && img->get_info()->prc_stage != h.prc_stage)
|
|
||||||
{
|
{
|
||||||
int stage = img->get_info()->prc_stage;
|
int stage = img->get_info()->prc_stage;
|
||||||
char alg[128] = { 0 };
|
char alg[128] = { 0 };
|
||||||
|
@ -272,12 +270,35 @@ void hg_scanner::process_image(image_holder_ptr img)
|
||||||
sprintf(alg, "%04X_Unk", stage);
|
sprintf(alg, "%04X_Unk", stage);
|
||||||
img->save_2_file(dump_path_.c_str(), alg);
|
img->save_2_file(dump_path_.c_str(), alg);
|
||||||
}
|
}
|
||||||
if (img->get_info()->prc_stage == h.prc_stage)
|
|
||||||
|
if (img->get_info()->format != IMG_FMT_BMP)
|
||||||
{
|
{
|
||||||
|
// decode ...
|
||||||
|
#ifdef TEST_HGSCANNER
|
||||||
|
#else
|
||||||
|
cv::ImreadModes mode = img->get_info()->channels == 1 ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR;
|
||||||
|
std::vector<uchar> buf(img->data_length());
|
||||||
|
|
||||||
|
memcpy(buf.data(), img->data(), img->data_length());
|
||||||
|
cv::Mat mat(cv::imdecode(buf, mode));
|
||||||
|
|
||||||
|
PACKIMAGE head(*img->get_info());
|
||||||
|
image_holder *ptr = nullptr;
|
||||||
|
uint32_t size = mat.total() * mat.channels();
|
||||||
|
|
||||||
|
head.data_size = size;
|
||||||
|
head.format = IMG_FMT_BMP;
|
||||||
|
ptr = new image_holder(&head);
|
||||||
|
ptr->put_data(mat.ptr(), &size);
|
||||||
|
img = ptr;
|
||||||
|
addref = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addref)
|
||||||
img->add_ref();
|
img->add_ref();
|
||||||
final_imgs_.save(img, true);
|
final_imgs_.save(img, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
image_holder_ptr hg_scanner::wait_image(void)
|
image_holder_ptr hg_scanner::wait_image(void)
|
||||||
{
|
{
|
||||||
image_holder_ptr ptr = nullptr;
|
image_holder_ptr ptr = nullptr;
|
||||||
|
@ -488,6 +509,11 @@ int hg_scanner::get_image_info(SANE_Parameters* pii)
|
||||||
pii->bytes_per_line = (ptr->get_info()->bpp * ptr->get_info()->width * ptr->get_info()->channels + 7) / 8; // no 4-bytes align
|
pii->bytes_per_line = (ptr->get_info()->bpp * ptr->get_info()->width * ptr->get_info()->channels + 7) / 8; // no 4-bytes align
|
||||||
pii->depth = ptr->get_info()->bpp; // 此处指每一个颜色分量的位深,我们的扫描仪固定为“8”
|
pii->depth = ptr->get_info()->bpp; // 此处指每一个颜色分量的位深,我们的扫描仪固定为“8”
|
||||||
pii->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离,则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”,所以也为true
|
pii->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离,则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”,所以也为true
|
||||||
|
if (ptr->get_info()->format == IMG_FMT_JPEG)
|
||||||
|
pii->format = (SANE_Frame)SANE_FRAME_JPEG;
|
||||||
|
else if (ptr->get_info()->format == IMG_FMT_PNG)
|
||||||
|
pii->format = (SANE_Frame)SANE_FRAME_PNG;
|
||||||
|
else
|
||||||
pii->format = ptr->get_info()->channels == 3 ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
|
pii->format = ptr->get_info()->channels == 3 ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
|
||||||
pii->lines = ptr->get_info()->height;
|
pii->lines = ptr->get_info()->height;
|
||||||
pii->pixels_per_line = ptr->get_info()->width;
|
pii->pixels_per_line = ptr->get_info()->width;
|
||||||
|
@ -647,3 +673,4 @@ int hg_scanner::file_transfer(const char* local, const char* remote, bool to_rem
|
||||||
|
|
||||||
return scanner_->file_transfer(local, remote, to_remote, prog);
|
return scanner_->file_transfer(local, remote, to_remote, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -451,9 +451,9 @@ void async_usb_host::create_worker_threads(void)
|
||||||
void(async_usb_host:: * p)(void) = &async_usb_host::thread_pump_task;
|
void(async_usb_host:: * p)(void) = &async_usb_host::thread_pump_task;
|
||||||
void(async_usb_host:: * r)(void) = &async_usb_host::thread_read_bulk;
|
void(async_usb_host:: * r)(void) = &async_usb_host::thread_read_bulk;
|
||||||
void(async_usb_host:: * w)(void) = &async_usb_host::thread_write_bulk;
|
void(async_usb_host:: * w)(void) = &async_usb_host::thread_write_bulk;
|
||||||
worker_.start(thread_p, "async_usb_host::thread_pump_task", *(void**)&p);
|
worker_.start(thread_p, 0, "async_usb_host::thread_pump_task", *(void**)&p);
|
||||||
worker_.start(thread_w, "async_usb_host::thread_write_bulk", *(void**)&w);
|
worker_.start(thread_w, 0, "async_usb_host::thread_write_bulk", *(void**)&w);
|
||||||
worker_.start(thread_r, "async_usb_host::thread_read_bulk", *(void**)&r);
|
worker_.start(thread_r, 0, "async_usb_host::thread_read_bulk", *(void**)&r);
|
||||||
#else
|
#else
|
||||||
thread_w_.reset(new std::thread(&async_usb_host::thread_write_bulk, this));
|
thread_w_.reset(new std::thread(&async_usb_host::thread_write_bulk, this));
|
||||||
thread_r_.reset(new std::thread(&async_usb_host::thread_read_bulk, this));
|
thread_r_.reset(new std::thread(&async_usb_host::thread_read_bulk, this));
|
||||||
|
|
|
@ -183,7 +183,7 @@ usb_manager::usb_manager() : run_(true)
|
||||||
thread_notify_usb_event();
|
thread_notify_usb_event();
|
||||||
};
|
};
|
||||||
void(usb_manager:: * pnp)(void) = &usb_manager::thread_notify_usb_event;
|
void(usb_manager:: * pnp)(void) = &usb_manager::thread_notify_usb_event;
|
||||||
usb_notify_thread_.start(tf, "usb_manager::thread_notify_usb_event", *(void**)&pnp);
|
usb_notify_thread_.start(tf, 0, "usb_manager::thread_notify_usb_event", *(void**)&pnp);
|
||||||
#else
|
#else
|
||||||
if (!usb_notify_thread_.get())
|
if (!usb_notify_thread_.get())
|
||||||
{
|
{
|
||||||
|
@ -281,7 +281,7 @@ void usb_manager::init_notify_thread()
|
||||||
thread_trigger_usb_event();
|
thread_trigger_usb_event();
|
||||||
};
|
};
|
||||||
void(usb_manager:: * t)(void) = &usb_manager::thread_trigger_usb_event;
|
void(usb_manager:: * t)(void) = &usb_manager::thread_trigger_usb_event;
|
||||||
usb_monitor_thread_.start(tf, "usb_manager::thread_trigger_usb_event", *(void**)&t);
|
usb_monitor_thread_.start(tf, 0, "usb_manager::thread_trigger_usb_event", *(void**)&t);
|
||||||
#else
|
#else
|
||||||
if(!usb_monitor_thread_.get())
|
if(!usb_monitor_thread_.get())
|
||||||
{
|
{
|
||||||
|
|
|
@ -543,13 +543,36 @@ int dyn_mem::fetch_data(void* buf, uint32_t* size)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
dyn_mem_shared::dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy, void* param)
|
dyn_mem_shared::dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy)
|
||||||
: dyn_mem(buf, size), destroy_(destroy), param_(param)
|
: dyn_mem(buf, size), destroy_(destroy)
|
||||||
{}
|
{
|
||||||
|
memset(param_, 0, sizeof(param_));
|
||||||
|
}
|
||||||
dyn_mem_shared::~dyn_mem_shared()
|
dyn_mem_shared::~dyn_mem_shared()
|
||||||
{
|
{
|
||||||
if(destroy_)
|
if(destroy_)
|
||||||
destroy_(this, param_);
|
destroy_(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dyn_mem_shared::set_param(void* param, int index)
|
||||||
|
{
|
||||||
|
if(index >= 0 && index < _countof(param_))
|
||||||
|
{
|
||||||
|
param_[index] = param;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void* dyn_mem_shared::get_param(int index)
|
||||||
|
{
|
||||||
|
if(index >= 0 && index < _countof(param_))
|
||||||
|
return param_[index];
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -905,7 +928,8 @@ uint8_t* file_map::buffer(void)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// image_packet
|
// image_packet
|
||||||
image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid
|
image_packet::image_packet(LPPACKIMAGE head, std::shared_ptr<std::vector<uchar>> img
|
||||||
|
, uint32_t scanid
|
||||||
, const void* info, size_t info_size)
|
, const void* info, size_t info_size)
|
||||||
: img_(img), offset_(0), info_over_(false)
|
: img_(img), offset_(0), info_over_(false)
|
||||||
{
|
{
|
||||||
|
@ -913,7 +937,6 @@ image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid
|
||||||
LPPACKIMAGE pimg = nullptr;
|
LPPACKIMAGE pimg = nullptr;
|
||||||
|
|
||||||
paper_ind_ = head->pos.paper_ind;
|
paper_ind_ = head->pos.paper_ind;
|
||||||
img->add_ref();
|
|
||||||
if(info && info_size)
|
if(info && info_size)
|
||||||
info_ = std::string((const char*)info, info_size);
|
info_ = std::string((const char*)info, info_size);
|
||||||
else
|
else
|
||||||
|
@ -926,7 +949,7 @@ image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid
|
||||||
pack->payload_len = sizeof(PACKIMAGE);
|
pack->payload_len = sizeof(PACKIMAGE);
|
||||||
|
|
||||||
memcpy(pimg, head, sizeof(*pimg));
|
memcpy(pimg, head, sizeof(*pimg));
|
||||||
pimg->data_size = img->get_rest();
|
pimg->data_size = img->size();
|
||||||
pimg->info_size = info_size;
|
pimg->info_size = info_size;
|
||||||
|
|
||||||
head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE));
|
head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE));
|
||||||
|
@ -947,7 +970,6 @@ image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid
|
||||||
image_packet::~image_packet()
|
image_packet::~image_packet()
|
||||||
{
|
{
|
||||||
head_->release();
|
head_->release();
|
||||||
img_->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool image_packet::is_memory_block(void)
|
bool image_packet::is_memory_block(void)
|
||||||
|
@ -956,7 +978,7 @@ bool image_packet::is_memory_block(void)
|
||||||
}
|
}
|
||||||
uint32_t image_packet::get_rest(void)
|
uint32_t image_packet::get_rest(void)
|
||||||
{
|
{
|
||||||
return head_->get_rest() + info_.length() + img_->get_rest() - offset_;
|
return head_->get_rest() + info_.length() + img_->size() - offset_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// following API valid when is_memory_block() return true
|
// following API valid when is_memory_block() return true
|
||||||
|
@ -1000,15 +1022,15 @@ int image_packet::fetch_data(void* buf, uint32_t* size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(*size + offset_ >= img_->get_rest())
|
if(*size + offset_ >= img_->size())
|
||||||
{
|
{
|
||||||
memcpy(buf, img_->ptr() + offset_, img_->get_rest() - offset_);
|
memcpy(buf, img_->data() + offset_, img_->size() - offset_);
|
||||||
*size = img_->get_rest() - offset_;
|
*size = img_->size() - offset_;
|
||||||
offset_ = img_->get_rest();
|
offset_ = img_->size();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(buf, img_->ptr() + offset_, *size);
|
memcpy(buf, img_->data() + offset_, *size);
|
||||||
offset_ += *size;
|
offset_ += *size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#define CLS_PTR(cls) typedef cls* cls##_ptr;
|
#define CLS_PTR(cls) typedef cls* cls##_ptr;
|
||||||
|
#ifndef uchar
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -213,7 +216,7 @@ public:
|
||||||
|
|
||||||
// #define STAT_MEM
|
// #define STAT_MEM
|
||||||
#define BEFORE_DESTROY_RET void
|
#define BEFORE_DESTROY_RET void
|
||||||
#define BEFORE_DESTROY_PARAM dyn_mem* mem, void* param
|
#define BEFORE_DESTROY_PARAM dyn_mem_shared* mem
|
||||||
#define BEFORE_DESTROY_FUNC std::function<BEFORE_DESTROY_RET(BEFORE_DESTROY_PARAM)>
|
#define BEFORE_DESTROY_FUNC std::function<BEFORE_DESTROY_RET(BEFORE_DESTROY_PARAM)>
|
||||||
|
|
||||||
class dyn_mem : public data_source
|
class dyn_mem : public data_source
|
||||||
|
@ -263,13 +266,17 @@ public:
|
||||||
class dyn_mem_shared : public dyn_mem
|
class dyn_mem_shared : public dyn_mem
|
||||||
{
|
{
|
||||||
BEFORE_DESTROY_FUNC destroy_ = BEFORE_DESTROY_FUNC();
|
BEFORE_DESTROY_FUNC destroy_ = BEFORE_DESTROY_FUNC();
|
||||||
void* param_ = nullptr;
|
void* param_[4];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC(), void* param = nullptr);
|
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC());
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~dyn_mem_shared();
|
~dyn_mem_shared();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool set_param(void* param, int index = 0);
|
||||||
|
void* get_param(int index = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class file_reader : public data_source
|
class file_reader : public data_source
|
||||||
|
@ -305,7 +312,8 @@ public:
|
||||||
|
|
||||||
class image_packet : public data_source
|
class image_packet : public data_source
|
||||||
{
|
{
|
||||||
dyn_mem* img_;
|
// dyn_mem* img_;
|
||||||
|
std::shared_ptr<std::vector<uchar>> img_;
|
||||||
dyn_mem* head_;
|
dyn_mem* head_;
|
||||||
uint32_t offset_;
|
uint32_t offset_;
|
||||||
uint32_t paper_ind_ = 0;
|
uint32_t paper_ind_ = 0;
|
||||||
|
@ -314,7 +322,7 @@ class image_packet : public data_source
|
||||||
std::string pos_str_;
|
std::string pos_str_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
image_packet(LPPACKIMAGE head, dyn_mem* img, uint32_t scanid, const void* info = nullptr, size_t info_size = 0);
|
image_packet(LPPACKIMAGE head, std::shared_ptr<std::vector<uchar>> img, uint32_t scanid, const void* info = nullptr, size_t info_size = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~image_packet();
|
virtual ~image_packet();
|
||||||
|
|
|
@ -40,6 +40,12 @@
|
||||||
// protocol version, The first thing to do after connecting is to check whether the field is compatible !!!
|
// protocol version, The first thing to do after connecting is to check whether the field is compatible !!!
|
||||||
#define PROTOCOL_VER MAKE_WORD(0, 1)
|
#define PROTOCOL_VER MAKE_WORD(0, 1)
|
||||||
|
|
||||||
|
// resource manager callback
|
||||||
|
#define CHK_RES_FUNC std::function<bool(int, bool, int)>
|
||||||
|
#define DECL_CHK_RES_FUNC(where, n) \
|
||||||
|
auto n = [where](int task, bool wait, int to_ms) -> bool
|
||||||
|
|
||||||
|
|
||||||
// NOTE: All text transmitted by pack cmd is in UTF-8 format !!!
|
// NOTE: All text transmitted by pack cmd is in UTF-8 format !!!
|
||||||
|
|
||||||
enum cancel_io
|
enum cancel_io
|
||||||
|
@ -64,6 +70,15 @@ enum woker_status
|
||||||
WORKER_STATUS_RESET, // in reset(close and reopen) process
|
WORKER_STATUS_RESET, // in reset(close and reopen) process
|
||||||
WORKER_STATUS_WAIT_RESOURCE, // wait resource
|
WORKER_STATUS_WAIT_RESOURCE, // wait resource
|
||||||
};
|
};
|
||||||
|
enum _task
|
||||||
|
{
|
||||||
|
TASK_NONE = 0,
|
||||||
|
TASK_EP0,
|
||||||
|
TASK_BULK_IN,
|
||||||
|
TASK_BULK_OUT,
|
||||||
|
TASK_CAPTURER,
|
||||||
|
TASK_IMG_PROCESSOR,
|
||||||
|
};
|
||||||
|
|
||||||
enum packet_cmd
|
enum packet_cmd
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
#define SIZE_MB(n) SIZE_KB((n) * 1024)
|
#define SIZE_MB(n) SIZE_KB((n) * 1024)
|
||||||
#define SIZE_GB(n) SIZE_MB((n) * 1024)
|
#define SIZE_GB(n) SIZE_MB((n) * 1024)
|
||||||
|
|
||||||
#define SEC_2_MS(s) ((s) * 1000)
|
#define USEC_2_NS(us) ((long)(us) * 1000)
|
||||||
#define MSEC_2_US(ms) ((ms) * 1000)
|
#define MSEC_2_US(ms) ((long)(ms) * 1000)
|
||||||
|
#define SEC_2_MS(s) ((long)(s) * 1000)
|
||||||
|
#define MSEC_2_NS(ms) USEC_2_NS(MSEC_2_US(ms))
|
||||||
#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s))
|
#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s))
|
||||||
|
#define SEC_2_NS(s) USEC_2_NS(SEC_2_US(s))
|
||||||
|
|
||||||
#define MM_PER_INCH 25.4f
|
#define MM_PER_INCH 25.4f
|
||||||
#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001
|
#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001
|
||||||
|
@ -104,6 +107,11 @@ typedef struct _size
|
||||||
u_int32_t cx;
|
u_int32_t cx;
|
||||||
u_int32_t cy;
|
u_int32_t cy;
|
||||||
}SIZE, *LPSIZE;
|
}SIZE, *LPSIZE;
|
||||||
|
typedef struct _point
|
||||||
|
{
|
||||||
|
u_int32_t x;
|
||||||
|
u_int32_t y;
|
||||||
|
}POINT, *LPPOINT;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@ -175,6 +183,10 @@ extern uint64_t GetCurrentThreadId(void);
|
||||||
#define FSEEK _fseeki64
|
#define FSEEK _fseeki64
|
||||||
#define FTELL _ftelli64
|
#define FTELL _ftelli64
|
||||||
#define pid_t int
|
#define pid_t int
|
||||||
|
#define pthread_t HANDLE
|
||||||
|
|
||||||
|
#define _GLIBCXX_TXN_SAFE_DYN
|
||||||
|
#define _GLIBCXX_USE_NOEXCEPT
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,410 @@
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define PIPE_PROTO_VER MAKEWORD(0, 1)
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ipc class
|
||||||
|
namespace devui
|
||||||
|
{
|
||||||
|
class pipe_reader : public refer
|
||||||
|
{
|
||||||
|
std::string pipe_path_;
|
||||||
|
int fd_ = -1;
|
||||||
|
safe_thread worker_;
|
||||||
|
volatile bool run_ = true;
|
||||||
|
std::function<void(uint8_t*, size_t)> handler_;
|
||||||
|
|
||||||
|
void worker(void)
|
||||||
|
{
|
||||||
|
uint8_t buf[512] = {0};
|
||||||
|
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
int len = read(fd_, buf, sizeof(buf));
|
||||||
|
if(len == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
handler_(buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
pipe_reader(const char* fifo, std::function<void(uint8_t*, size_t)> h) : pipe_path_(fifo), handler_(h)
|
||||||
|
{
|
||||||
|
auto r = [this](void) -> void
|
||||||
|
{
|
||||||
|
int cycle = 0;
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
fd_ = ::open(pipe_path_.c_str(), O_RDONLY);
|
||||||
|
utils::to_log(LOG_LEVEL_ALL, "open pipe_reader(%s) %d times = %d\n", ++cycle, fd_);
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
worker();
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
::close(fd_);
|
||||||
|
fd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
worker_.start(r, SIZE_MB(1), "worker", (void*)&pipe_reader::worker);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual ~pipe_reader()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool is_ready(void)
|
||||||
|
{
|
||||||
|
return fd_ != -1;
|
||||||
|
}
|
||||||
|
void stop(void)
|
||||||
|
{
|
||||||
|
run_ = false;
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
int fd = fd_;
|
||||||
|
fd_ = -1;
|
||||||
|
::close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class pipe_sender : public refer
|
||||||
|
{
|
||||||
|
std::string pipe_path_;
|
||||||
|
int fd_ = -1;
|
||||||
|
safe_thread worker_;
|
||||||
|
volatile bool run_ = true;
|
||||||
|
safe_fifo<std::string> sent_que_;
|
||||||
|
|
||||||
|
void worker(void)
|
||||||
|
{
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
std::string cont("");
|
||||||
|
if(sent_que_.take(cont, true))
|
||||||
|
{
|
||||||
|
int s = 0, off = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
s = write(fd_, cont.c_str() + off, cont.length() - off);
|
||||||
|
if(s == -1)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Send UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
off += s;
|
||||||
|
}while(off < cont.length());
|
||||||
|
if(s == -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
pipe_sender(const char* fifo) : pipe_path_(fifo), sent_que_("sent-que")
|
||||||
|
{
|
||||||
|
sent_que_.enable_wait_log(false);
|
||||||
|
|
||||||
|
auto r = [this](void) -> void
|
||||||
|
{
|
||||||
|
int cycle = 0;
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
fd_ = ::open(pipe_path_.c_str(), O_WRONLY);
|
||||||
|
utils::to_log(LOG_LEVEL_ALL, "open pipe_sender(%s) %d times = %d\n", ++cycle, fd_);
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
worker();
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
::close(fd_);
|
||||||
|
fd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
worker_.start(r, SIZE_MB(1), "worker", (void*)&pipe_sender::worker);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual ~pipe_sender()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool is_ready(void)
|
||||||
|
{
|
||||||
|
return fd_ != -1;
|
||||||
|
}
|
||||||
|
void stop(void)
|
||||||
|
{
|
||||||
|
run_ = false;
|
||||||
|
if(fd_ != -1)
|
||||||
|
{
|
||||||
|
int fd = fd_;
|
||||||
|
fd_ = -1;
|
||||||
|
::close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void send(std::string& msg)
|
||||||
|
{
|
||||||
|
sent_que_.save(msg, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ui_messenger
|
||||||
|
{
|
||||||
|
std::function<void(LPMSGSTREAM)> cb_;
|
||||||
|
safe_fifo<std::string> sent_que_;
|
||||||
|
volatile bool run_ = true;
|
||||||
|
bool ui_;
|
||||||
|
bool ready_ = true;
|
||||||
|
safe_thread workers_;
|
||||||
|
int fdo_ = -1;
|
||||||
|
int fdi_ = -1;
|
||||||
|
|
||||||
|
std::string fmode(int m)
|
||||||
|
{
|
||||||
|
if(m == O_RDONLY)
|
||||||
|
return "O_RDONLY";
|
||||||
|
if(m == O_WRONLY)
|
||||||
|
return "O_WRONLY";
|
||||||
|
|
||||||
|
return "Unk";
|
||||||
|
}
|
||||||
|
void init(void)
|
||||||
|
{
|
||||||
|
const char* fifo[] = {"/tmp/worker", "/tmp/ui"};
|
||||||
|
int mode[] = {O_RDONLY, O_WRONLY};
|
||||||
|
int *fd[] = {&fdi_, &fdo_};
|
||||||
|
|
||||||
|
mkfifo(fifo[!ui_], 0777);
|
||||||
|
mkfifo(fifo[ui_], 0777);
|
||||||
|
*fd[ui_] = open(fifo[1], mode[ui_]);
|
||||||
|
utils::to_log(LOG_LEVEL_ALL, "open pipe(%s) = %d\n", fifo[1], *fd[ui_]);
|
||||||
|
*fd[!ui_] = open(fifo[0], mode[!ui_]);
|
||||||
|
utils::to_log(LOG_LEVEL_ALL, "open pipe(%s) = %d\n", fifo[0], *fd[!ui_]);
|
||||||
|
|
||||||
|
if(fdo_ == -1 || fdi_ == -1)
|
||||||
|
{
|
||||||
|
printf("Out fd = %d, In fd = %d\n", fdo_, fdi_);
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto r = [this](void) -> void
|
||||||
|
{
|
||||||
|
receiver();
|
||||||
|
};
|
||||||
|
auto s = [this](void) -> void
|
||||||
|
{
|
||||||
|
sender();
|
||||||
|
};
|
||||||
|
workers_.start(r, SIZE_MB(1), "receiver");
|
||||||
|
workers_.start(s, SIZE_MB(1), "sender");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void close(void)
|
||||||
|
{
|
||||||
|
ready_ = false;
|
||||||
|
if(fdo_ != -1)
|
||||||
|
::close(fdo_);
|
||||||
|
if(fdi_ != -1)
|
||||||
|
::close(fdi_);
|
||||||
|
fdi_ = fdo_ = -1;
|
||||||
|
}
|
||||||
|
void receiver(void)
|
||||||
|
{
|
||||||
|
std::string rcv("");
|
||||||
|
char buf[300] = {0};
|
||||||
|
LPMSGSTREAM pack = nullptr;
|
||||||
|
chronograph watch;
|
||||||
|
|
||||||
|
printf("ui-receiver running ...\n");
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
watch.reset();
|
||||||
|
int r = read(fdi_, buf, _countof(buf));
|
||||||
|
if(r == -1)
|
||||||
|
{
|
||||||
|
printf("Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
this->close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code
|
||||||
|
{
|
||||||
|
// peer closed, wait 10ms ...
|
||||||
|
if(watch.elapse_ms() > 10)
|
||||||
|
{
|
||||||
|
MSGSTREAM ms;
|
||||||
|
memset(&ms, 0, sizeof(ms));
|
||||||
|
ms.ver = PIPE_PROTO_VER;
|
||||||
|
ms.msg = UI_STATUS_PEER_CLOSED;
|
||||||
|
cb_(&ms);
|
||||||
|
|
||||||
|
printf("PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcv += std::string(buf, r);
|
||||||
|
if(rcv.length())
|
||||||
|
{
|
||||||
|
int off = 0;
|
||||||
|
pack = (LPMSGSTREAM)&rcv[off];
|
||||||
|
while(pack->whole_size() <= rcv.length() - off)
|
||||||
|
{
|
||||||
|
cb_(pack);
|
||||||
|
off += pack->whole_size();
|
||||||
|
pack = (LPMSGSTREAM)&rcv[off];
|
||||||
|
}
|
||||||
|
if(off)
|
||||||
|
rcv.erase(0, off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("ui-receiver exited.\n");
|
||||||
|
}
|
||||||
|
void sender(void)
|
||||||
|
{
|
||||||
|
printf("ui-sender running ...\n");
|
||||||
|
while(run_)
|
||||||
|
{
|
||||||
|
std::string cont("");
|
||||||
|
if(sent_que_.take(cont, true))
|
||||||
|
{
|
||||||
|
int s = 0, off = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
s = write(fdo_, cont.c_str() + off, cont.length() - off);
|
||||||
|
if(s == -1)
|
||||||
|
{
|
||||||
|
printf("Send UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Send UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
this->close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
off += s;
|
||||||
|
}while(off < cont.length());
|
||||||
|
if(s == -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("ui-sender exited.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ui_messenger(std::function<void(LPMSGSTREAM)> uicb
|
||||||
|
, bool ui) : sent_que_("ui-sent-que")
|
||||||
|
, cb_(uicb), ui_(ui)
|
||||||
|
{
|
||||||
|
sent_que_.enable_wait_log(false);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
~ui_messenger()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool send(std::string& msg)
|
||||||
|
{
|
||||||
|
if(ready_)
|
||||||
|
sent_que_.save(msg, true);
|
||||||
|
|
||||||
|
return ready_;
|
||||||
|
}
|
||||||
|
void stop(void)
|
||||||
|
{
|
||||||
|
sent_que_.trigger();
|
||||||
|
run_ = false;
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// interface
|
||||||
|
static MUTEX msg_lk_;
|
||||||
|
static devui::ui_messenger *msgr = nullptr;
|
||||||
|
|
||||||
|
namespace devui
|
||||||
|
{
|
||||||
|
void init_ui(std::function<void(LPMSGSTREAM)> uicb, bool ui)
|
||||||
|
{
|
||||||
|
SIMPLE_LOCK(msg_lk_);
|
||||||
|
if(!msgr)
|
||||||
|
msgr = new ui_messenger(uicb, ui);
|
||||||
|
}
|
||||||
|
void uninit_ui(void)
|
||||||
|
{
|
||||||
|
SIMPLE_LOCK(msg_lk_);
|
||||||
|
if(msgr)
|
||||||
|
{
|
||||||
|
msgr->stop();
|
||||||
|
delete msgr;
|
||||||
|
}
|
||||||
|
msgr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool send_message(uint32_t msgid, uint8_t* data, uint8_t size)
|
||||||
|
{
|
||||||
|
std::string stream("");
|
||||||
|
MSGSTREAM pack;
|
||||||
|
bool ret = false;
|
||||||
|
size_t fix = sizeof(pack.data);
|
||||||
|
|
||||||
|
memset(&pack, 0, sizeof(pack));
|
||||||
|
pack.ver = PIPE_PROTO_VER;
|
||||||
|
pack.msg = msgid;
|
||||||
|
pack.size = size;
|
||||||
|
if(size > fix)
|
||||||
|
{
|
||||||
|
memcpy(pack.data, data, fix);
|
||||||
|
stream = std::string((char*)&pack, sizeof(pack));
|
||||||
|
stream += std::string((char*)data + fix, size - fix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(pack.data, data, size);
|
||||||
|
stream = std::string((char*)&pack, sizeof(pack));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SIMPLE_LOCK(msg_lk_);
|
||||||
|
if(msgr)
|
||||||
|
ret = msgr->send(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool send_status_message(uint32_t msgid, int align_h, int align_v, int font, int clears)
|
||||||
|
{
|
||||||
|
devui::STATMSG msg;
|
||||||
|
|
||||||
|
msg.msg_words_id = msgid;
|
||||||
|
msg.align_h = align_h;
|
||||||
|
msg.align_v = align_v;
|
||||||
|
msg.clear = clears;
|
||||||
|
msg.font = font;
|
||||||
|
msg.reserved = 0;
|
||||||
|
|
||||||
|
return send_message(devui::UI_STATUS_MESSAGE, (uint8_t*)&msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Purpose: IPC methods between scanner and user-interface (keyboard, monitor, power, ...)
|
||||||
|
//
|
||||||
|
// Date: 2024-01-09
|
||||||
|
//
|
||||||
|
// Thinking: This module can provide services independently of the scanner-service program
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace devui
|
||||||
|
{
|
||||||
|
enum scan
|
||||||
|
{
|
||||||
|
SCAN_STOPPED = 0, // scanning work is stopped
|
||||||
|
SCAN_PAUSED, // finished ONE turn scanning in auto-scan
|
||||||
|
SCAN_NORMAL,
|
||||||
|
SCAN_COUNT_MODE,
|
||||||
|
};
|
||||||
|
enum uicmd
|
||||||
|
{
|
||||||
|
UI_CMD_COUNT_PAPER = 0x10,
|
||||||
|
UI_CMD_STOP_SCAN,
|
||||||
|
|
||||||
|
UI_CMD_CLEAN_PASSWAY = 0x30,
|
||||||
|
|
||||||
|
UI_STATUS_SCANNING = 0x1000, // begin scanning. data: (LPSCANSTREAM)
|
||||||
|
UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: (uint32_t*)milliseconds for paper pass through
|
||||||
|
UI_STATUS_MESSAGE, // status message, hold screen. data: LPSTATMSG
|
||||||
|
|
||||||
|
UI_STATUS_PEER_CLOSED = 0x8000, // peer closed.
|
||||||
|
};
|
||||||
|
enum align_component
|
||||||
|
{
|
||||||
|
ALIGN_COMPONENT_HEAD = 0,
|
||||||
|
ALIGN_COMPONENT_MID,
|
||||||
|
ALIGN_COMPONENT_TAIL,
|
||||||
|
};
|
||||||
|
enum clear_method
|
||||||
|
{
|
||||||
|
CLEAR_NONE = 0, // no clear
|
||||||
|
CLEAR_ALL, // clear all screen
|
||||||
|
CLEAR_LINE, // clear the lines which the content will output
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct _msg_stream
|
||||||
|
{
|
||||||
|
uint16_t ver;
|
||||||
|
uint16_t size; // bytes of data
|
||||||
|
uint32_t msg; // uicmd
|
||||||
|
uint8_t data[4];
|
||||||
|
|
||||||
|
uint32_t whole_size(void)
|
||||||
|
{
|
||||||
|
if(size > sizeof(data))
|
||||||
|
return sizeof(*this) + size - sizeof(data);
|
||||||
|
else
|
||||||
|
return sizeof(*this);
|
||||||
|
}
|
||||||
|
}MSGSTREAM, *LPMSGSTREAM;
|
||||||
|
typedef struct _scan_stream
|
||||||
|
{
|
||||||
|
uint32_t mode : 5; // see enum scan
|
||||||
|
uint32_t speed : 27;
|
||||||
|
uint32_t err; // err message word ID, 0 is normal
|
||||||
|
}SCANSTREAM, *LPSCANSTREAM;
|
||||||
|
typedef struct _status_msg
|
||||||
|
{
|
||||||
|
uint32_t msg_words_id; // words.h
|
||||||
|
uint32_t align_h : 3; // align_component
|
||||||
|
uint32_t align_v : 3; // align_component
|
||||||
|
uint32_t clear : 4; // clear screen method
|
||||||
|
uint32_t font : 8; // font size
|
||||||
|
uint32_t reserved : 14;
|
||||||
|
}STATMSG, *LPSTATMSG;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
void init_ui(std::function<void(LPMSGSTREAM)> uicb, bool ui);
|
||||||
|
void uninit_ui(void);
|
||||||
|
|
||||||
|
bool send_message(uint32_t msgid, uint8_t* data = nullptr, uint8_t size = 0); // re-init if return false
|
||||||
|
bool send_status_message(uint32_t msgid, int align_h = ALIGN_COMPONENT_MID, int align_v = ALIGN_COMPONENT_MID, int font = 16, int clears = CLEAR_ALL);
|
||||||
|
};
|
|
@ -1,12 +1,12 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include "ini_file.h"
|
#include "ini_file.h"
|
||||||
#include <huagao/brand.h>
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
|
#include <huagao/brand.h>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -218,6 +218,7 @@ class log_cls
|
||||||
FILE* file_;
|
FILE* file_;
|
||||||
int level_;
|
int level_;
|
||||||
int type_;
|
int type_;
|
||||||
|
int max_file_size_ = MAX_LOG_FILE_SIZE;
|
||||||
std::mutex lock_;
|
std::mutex lock_;
|
||||||
|
|
||||||
static log_cls* inst_;
|
static log_cls* inst_;
|
||||||
|
@ -256,15 +257,16 @@ class log_cls
|
||||||
static void log_file(const char* info, void* param, void* param2)
|
static void log_file(const char* info, void* param, void* param2)
|
||||||
{
|
{
|
||||||
FILE** file = (FILE**)param;
|
FILE** file = (FILE**)param;
|
||||||
|
log_cls *cls = (log_cls*)param2;
|
||||||
|
|
||||||
if (*file == nullptr)
|
if (*file == nullptr)
|
||||||
*file = create_log_file(((std::string*)param2)->c_str(), false);
|
*file = create_log_file(cls->path_file_.c_str(), false);
|
||||||
|
|
||||||
if (*file)
|
if (*file)
|
||||||
{
|
{
|
||||||
fwrite(info, 1, strlen(info), *file);
|
fwrite(info, 1, strlen(info), *file);
|
||||||
fflush(*file);
|
fflush(*file);
|
||||||
if (ftell(*file) >= MAX_LOG_FILE_SIZE)
|
if (ftell(*file) >= cls->max_file_size_)
|
||||||
{
|
{
|
||||||
fclose(*file);
|
fclose(*file);
|
||||||
remove(((std::string*)param2)->c_str());
|
remove(((std::string*)param2)->c_str());
|
||||||
|
@ -344,6 +346,10 @@ public:
|
||||||
{
|
{
|
||||||
level_ = level;
|
level_ = level;
|
||||||
}
|
}
|
||||||
|
void set_max_file_size(int size)
|
||||||
|
{
|
||||||
|
max_file_size_ = size;
|
||||||
|
}
|
||||||
int level(void)
|
int level(void)
|
||||||
{
|
{
|
||||||
return level_;
|
return level_;
|
||||||
|
@ -357,7 +363,7 @@ public:
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
|
|
||||||
log_(info, &file_, &path_file_);
|
log_(info, &file_, this);
|
||||||
}
|
}
|
||||||
std::string get_log_file_path(const char* dst = nullptr)
|
std::string get_log_file_path(const char* dst = nullptr)
|
||||||
{
|
{
|
||||||
|
@ -493,6 +499,24 @@ namespace utils
|
||||||
{
|
{
|
||||||
return u2m(m2u(ansi, CP_ACP).c_str(), CP_UTF8);
|
return u2m(m2u(ansi, CP_ACP).c_str(), CP_UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static time_t file_time_2_utc(FILETIME ft)
|
||||||
|
{
|
||||||
|
SYSTEMTIME sys = { 0 };
|
||||||
|
struct tm t = { 0 };
|
||||||
|
|
||||||
|
if (FileTimeToSystemTime(&ft, &sys))
|
||||||
|
{
|
||||||
|
t.tm_year = sys.wYear - 1900;
|
||||||
|
t.tm_mon = sys.wMonth - 1;
|
||||||
|
t.tm_mday = sys.wDay;
|
||||||
|
t.tm_hour = sys.wHour;
|
||||||
|
t.tm_min = sys.wMinute;
|
||||||
|
t.tm_sec = sys.wSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mktime(&t);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
// This function will return 'in' string if failed !
|
// This function will return 'in' string if failed !
|
||||||
static std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int *err, const char* ansi = "GBK")
|
static std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int *err, const char* ansi = "GBK")
|
||||||
|
@ -549,6 +573,169 @@ namespace utils
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int parse_utf8_char(const char*& str, char ch[])
|
||||||
|
{
|
||||||
|
uint8_t first = *str, ind = 0;
|
||||||
|
int ret = EINVAL;
|
||||||
|
|
||||||
|
if(first < 0x80)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
ch[ind++] = *str++;
|
||||||
|
}
|
||||||
|
else if(first >= 0x0c00)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
first &= 0x0fc;
|
||||||
|
while(first & 0x80)
|
||||||
|
{
|
||||||
|
ch[ind] = str[ind];
|
||||||
|
if(ch[ind] == 0)
|
||||||
|
{
|
||||||
|
ret = ENODATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ind++;
|
||||||
|
first <<= 1;
|
||||||
|
}
|
||||||
|
if(ret == 0)
|
||||||
|
str += ind;
|
||||||
|
|
||||||
|
}
|
||||||
|
ch[ind++] = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int utf16_2_8(unsigned short* &in, char ch[])
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int ret = 0, used = 0;
|
||||||
|
|
||||||
|
if(in[0] >= 0 && in[0] <= 0x7f)
|
||||||
|
{
|
||||||
|
ch[len++] = *in++;
|
||||||
|
}
|
||||||
|
else if(in[0] >= 0x0dc00 && in[0] <= 0x0dfff)
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int val = in[0];
|
||||||
|
if(in[0] >= 0x0d800 && in[0] <= 0x0dbff)
|
||||||
|
{
|
||||||
|
if(in[1] < 0x0dc00 || in[1] > 0x0dfff)
|
||||||
|
ret = EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
used = 1;
|
||||||
|
val = 0x10000 + (((val & 0x3ff) << 10) | (in[1] & 0x3ff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ret == 0)
|
||||||
|
{
|
||||||
|
static unsigned char lead[] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
char *ptr = ch;
|
||||||
|
|
||||||
|
used++;
|
||||||
|
len = 4;
|
||||||
|
if(val < 0x80)
|
||||||
|
len = 1;
|
||||||
|
else if(val < 0x800)
|
||||||
|
len = 2;
|
||||||
|
else if(val < 0x10000)
|
||||||
|
len = 3;
|
||||||
|
ptr += len;
|
||||||
|
switch(len)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
*--ptr = (val | 0x80) & 0x0bf;
|
||||||
|
val >>= 6;
|
||||||
|
case 3:
|
||||||
|
*--ptr = (val | 0x80) & 0x0bf;
|
||||||
|
val >>= 6;
|
||||||
|
case 2:
|
||||||
|
*--ptr = (val | 0x80) & 0x0bf;
|
||||||
|
val >>= 6;
|
||||||
|
case 1:
|
||||||
|
*--ptr = val | lead[len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ch[len++] = 0;
|
||||||
|
in += used;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int utf8_2_16(uint8_t* &in, uint16_t& ch)
|
||||||
|
{
|
||||||
|
static uint8_t lead[] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if(*in < 0x80)
|
||||||
|
{
|
||||||
|
ch = *in++;
|
||||||
|
}
|
||||||
|
else if(*in < 0x0E0)
|
||||||
|
{
|
||||||
|
ch = *in++;
|
||||||
|
ch &= ~0x0C0;
|
||||||
|
if(*in < 0x80)
|
||||||
|
ret = EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch <<= 6;
|
||||||
|
ch |= *in++ & 0x3f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(*in < 0x0F0)
|
||||||
|
{
|
||||||
|
ch = *in++;
|
||||||
|
ch &= ~0x0E0;
|
||||||
|
if(*in < 0x80)
|
||||||
|
ret = EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch <<= 6;
|
||||||
|
ch |= *in++ & 0x3f;
|
||||||
|
if(*in < 0x80)
|
||||||
|
ret = EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch <<= 6;
|
||||||
|
ch |= *in++ & 0x3f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int utf8_2_web(uint8_t* &in, std::string& web)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
while(*in)
|
||||||
|
{
|
||||||
|
uint16_t v = 0;
|
||||||
|
char buf[40] = {0};
|
||||||
|
|
||||||
|
ret = utf8_2_16(in, v);
|
||||||
|
if(ret)
|
||||||
|
break;
|
||||||
|
if(v < 0x80)
|
||||||
|
buf[0] = v;
|
||||||
|
else
|
||||||
|
sprintf(buf, "\\u%04X", v);
|
||||||
|
web += buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_command_result(const char* cmd, int len, int *err)
|
std::string get_command_result(const char* cmd, int len, int *err)
|
||||||
{
|
{
|
||||||
std::string result("");
|
std::string result("");
|
||||||
|
@ -788,8 +975,22 @@ namespace utils
|
||||||
FILE* dst = fopen(file, append ? "a+b" : "wb");
|
FILE* dst = fopen(file, append ? "a+b" : "wb");
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!dst)
|
while (!dst)
|
||||||
|
{
|
||||||
|
std::string dir(file);
|
||||||
|
size_t pos = dir.rfind(PATH_SEPARATOR[0]);
|
||||||
|
|
||||||
|
if(pos != std::string::npos)
|
||||||
|
{
|
||||||
|
dir.erase(pos);
|
||||||
|
create_folder(dir.c_str());
|
||||||
|
dst = fopen(file, append ? "a+b" : "wb");
|
||||||
|
if(dst)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return errno;
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
if(append && max_size != -1 && ftell(dst) >= max_size)
|
if(append && max_size != -1 && ftell(dst) >= max_size)
|
||||||
fseek(dst, 0, SEEK_SET);
|
fseek(dst, 0, SEEK_SET);
|
||||||
|
@ -896,6 +1097,26 @@ namespace utils
|
||||||
return str.c_str();
|
return str.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_stack_size(void)
|
||||||
|
{
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
#if OS_WIN
|
||||||
|
ULONG_PTR low = 0, up = 0;
|
||||||
|
GetCurrentThreadStackLimits(&low, &up);
|
||||||
|
size = up - low;
|
||||||
|
#else
|
||||||
|
pthread_attr_t attr;
|
||||||
|
|
||||||
|
pthread_getattr_np(pthread_self(), &attr);
|
||||||
|
// pthread_attr_init(&attr);
|
||||||
|
pthread_attr_getstacksize(&attr, (size_t*)&size);
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static bool hex_str_2_num(char hex, uint8_t* v)
|
static bool hex_str_2_num(char hex, uint8_t* v)
|
||||||
{
|
{
|
||||||
*v = 0;
|
*v = 0;
|
||||||
|
@ -1127,6 +1348,58 @@ namespace utils
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
int get_file_time(const char* file, uint64_t* born, uint64_t* modify, uint64_t* last_access)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
#if OS_WIN
|
||||||
|
if (born)
|
||||||
|
{
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA wfd = { 0 };
|
||||||
|
|
||||||
|
if (GetFileAttributesExA(file, GetFileExInfoStandard, &wfd))
|
||||||
|
{
|
||||||
|
if (born)
|
||||||
|
*born = file_time_2_utc(wfd.ftCreationTime);
|
||||||
|
if (modify)
|
||||||
|
*modify = file_time_2_utc(wfd.ftLastWriteTime);
|
||||||
|
if (last_access)
|
||||||
|
*last_access = file_time_2_utc(wfd.ftLastAccessTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = GetLastError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(born)
|
||||||
|
{
|
||||||
|
std::string str(get_command_result((std::string("stat -c %W ") + file).c_str()));
|
||||||
|
if(str.empty())
|
||||||
|
err = ENOENT;
|
||||||
|
else
|
||||||
|
*born = atoi(str.c_str());
|
||||||
|
}
|
||||||
|
if(modify && err == 0)
|
||||||
|
{
|
||||||
|
std::string str(get_command_result((std::string("stat -c %Y ") + file).c_str()));
|
||||||
|
if(str.empty())
|
||||||
|
err = ENOENT;
|
||||||
|
else
|
||||||
|
*modify = atoi(str.c_str());
|
||||||
|
}
|
||||||
|
if(last_access && err == 0)
|
||||||
|
{
|
||||||
|
std::string str(get_command_result((std::string("stat -c %X ") + file).c_str()));
|
||||||
|
if(str.empty())
|
||||||
|
err = ENOENT;
|
||||||
|
else
|
||||||
|
*last_access = atoi(str.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid)
|
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid)
|
||||||
{
|
{
|
||||||
|
@ -1283,6 +1556,10 @@ namespace utils
|
||||||
|
|
||||||
return std::move(file);
|
return std::move(file);
|
||||||
}
|
}
|
||||||
|
void set_log_file_max_size(int size)
|
||||||
|
{
|
||||||
|
log_cls::instance()->set_max_file_size(size);
|
||||||
|
}
|
||||||
void uninit(void)
|
void uninit(void)
|
||||||
{
|
{
|
||||||
log_info(("=====================================--Exited--" + std::to_string(GetCurrentProcessId()) + "=====================================\n\n\n\n").c_str(), LOG_LEVEL_FATAL);
|
log_info(("=====================================--Exited--" + std::to_string(GetCurrentProcessId()) + "=====================================\n\n\n\n").c_str(), LOG_LEVEL_FATAL);
|
||||||
|
@ -1405,6 +1682,26 @@ namespace utils
|
||||||
|
|
||||||
return std::move(std::string((char*)&bfh, sizeof(bfh)));
|
return std::move(std::string((char*)&bfh, sizeof(bfh)));
|
||||||
}
|
}
|
||||||
|
int save_bitmap(const char* file, int w, int h, int bpp, int dpix, int dpiy, void* bits)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
FILE* dst = fopen(file, "wb");
|
||||||
|
|
||||||
|
if(dst)
|
||||||
|
{
|
||||||
|
std::string bih(bitmap_info_header(w, h, bpp, dpix, dpiy)),
|
||||||
|
bfh(bitmap_file_header((BITMAPINFOHEADER*)&bih[0]));
|
||||||
|
|
||||||
|
fwrite(bfh.c_str(), 1, bfh.length(), dst);
|
||||||
|
fwrite(bih.c_str(), 1, bih.length(), dst);
|
||||||
|
fwrite(bits, 1, ((BITMAPINFOHEADER*)&bih[0])->biSizeImage, dst);
|
||||||
|
fclose(dst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = errno;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
bool run_get_message(HWND hwnd, UINT filter_min, UINT filter_max, std::function<bool(MSG*, bool*)> msghandler)
|
bool run_get_message(HWND hwnd, UINT filter_min, UINT filter_max, std::function<bool(MSG*, bool*)> msghandler)
|
||||||
|
@ -1770,6 +2067,7 @@ void chronograph::reset()
|
||||||
uint32_t global_info::page_size = 0;
|
uint32_t global_info::page_size = 0;
|
||||||
uint32_t global_info::page_map_size = 0;
|
uint32_t global_info::page_map_size = 0;
|
||||||
uint32_t global_info::cluster_size = 0;
|
uint32_t global_info::cluster_size = 0;
|
||||||
|
uint32_t global_info::stack_size = 0;
|
||||||
uint32_t global_info::gray_pallete[] = {0};
|
uint32_t global_info::gray_pallete[] = {0};
|
||||||
|
|
||||||
global_info::global_info()
|
global_info::global_info()
|
||||||
|
@ -1784,7 +2082,9 @@ global_info::global_info()
|
||||||
for(int i = 0; i < _countof(global_info::gray_pallete); ++i)
|
for(int i = 0; i < _countof(global_info::gray_pallete); ++i)
|
||||||
global_info::gray_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0));
|
global_info::gray_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0));
|
||||||
|
|
||||||
printf("Page size: %u\nMap size: %u\nCluster : %u\n", global_info::page_size, global_info::page_map_size, global_info::cluster_size);
|
path = utils::get_command_result("ulimit -s");
|
||||||
|
global_info::stack_size = SIZE_KB(atoi(path.c_str()));
|
||||||
|
printf("Page size: %u\nMap size: %u\nCluster : %u\nStck size: %u\n", global_info::page_size, global_info::page_map_size, global_info::cluster_size, global_info::stack_size);
|
||||||
}
|
}
|
||||||
global_info::~global_info()
|
global_info::~global_info()
|
||||||
{}
|
{}
|
||||||
|
@ -1896,8 +2196,19 @@ bool platform_event::wait(unsigned timeout)
|
||||||
to.tv_sec = time(nullptr);
|
to.tv_sec = time(nullptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
//*/
|
||||||
|
to.tv_nsec += MSEC_2_NS(timeout);
|
||||||
|
to.tv_sec += to.tv_nsec / SEC_2_NS(1);
|
||||||
|
to.tv_nsec %= SEC_2_NS(1);
|
||||||
|
/*/
|
||||||
to.tv_sec += timeout / 1000;
|
to.tv_sec += timeout / 1000;
|
||||||
to.tv_nsec += (long)((timeout % 1000) * 1000 * 1000);
|
to.tv_nsec += MSEC_2_NS(timeout % 1000);
|
||||||
|
if(to.tv_nsec >= SEC_2_NS(1))
|
||||||
|
{
|
||||||
|
to.tv_sec++;
|
||||||
|
to.tv_nsec -= SEC_2_NS(1);
|
||||||
|
}
|
||||||
|
////////*//////////////////
|
||||||
waited = sem_timedwait(&sem_, &to) == 0;
|
waited = sem_timedwait(&sem_, &to) == 0;
|
||||||
}
|
}
|
||||||
if (log_)
|
if (log_)
|
||||||
|
@ -2186,6 +2497,7 @@ safe_thread::~safe_thread()
|
||||||
|
|
||||||
void safe_thread::thread_worker(std::function<void(void)> func, std::string name, void* addr)
|
void safe_thread::thread_worker(std::function<void(void)> func, std::string name, void* addr)
|
||||||
{
|
{
|
||||||
|
printf("stack size of thread '%s': %u\n", name.c_str(), utils::get_stack_size());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "+++ safe_thread of '%s(addr: %p) - id: %p' is running ...\n", name.c_str(), addr, GetCurrentThreadId());
|
utils::to_log(LOG_LEVEL_DEBUG, "+++ safe_thread of '%s(addr: %p) - id: %p' is running ...\n", name.c_str(), addr, GetCurrentThreadId());
|
||||||
|
@ -2193,6 +2505,10 @@ void safe_thread::thread_worker(std::function<void(void)> func, std::string name
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "--- safe_thread of '%s - %p' exited.\n", name.c_str(), GetCurrentThreadId());
|
utils::to_log(LOG_LEVEL_DEBUG, "--- safe_thread of '%s - %p' exited.\n", name.c_str(), GetCurrentThreadId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
catch (exception_ex e)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%p - %s': %s\n", GetCurrentThreadId(), name.c_str(), e.what());
|
||||||
|
}
|
||||||
catch (std::exception e)
|
catch (std::exception e)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%p - %s': %s\n", GetCurrentThreadId(), name.c_str(), e.what());
|
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%p - %s': %s\n", GetCurrentThreadId(), name.c_str(), e.what());
|
||||||
|
@ -2215,18 +2531,72 @@ void safe_thread::thread_notify_exception(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if OS_WIN
|
||||||
|
DWORD WINAPI
|
||||||
|
#else
|
||||||
|
void*
|
||||||
|
#endif
|
||||||
|
safe_thread::raw_thread(void* lp)
|
||||||
|
{
|
||||||
|
safe_thread *obj = ((LPCRAWTHRD)lp)->obj;
|
||||||
|
std::function<void(void)> func = ((LPCRAWTHRD)lp)->func;
|
||||||
|
std::string name(((LPCRAWTHRD)lp)->name);
|
||||||
|
void* addr = ((LPCRAWTHRD)lp)->addr;
|
||||||
|
|
||||||
|
delete lp;
|
||||||
|
|
||||||
|
obj->thread_worker(func, name, addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void safe_thread::set_exception_handler(std::function<void(const char*)> on_exception)
|
void safe_thread::set_exception_handler(std::function<void(const char*)> on_exception)
|
||||||
{
|
{
|
||||||
excep_handler_ = on_exception;
|
excep_handler_ = on_exception;
|
||||||
}
|
}
|
||||||
int safe_thread::start(std::function<void(void)> f, const char* thread_name, void* addr)
|
int safe_thread::start(std::function<void(void)> f, std::size_t stack, const char* thread_name, void* addr)
|
||||||
{
|
{
|
||||||
SAFETHRD st;
|
SAFETHRD st;
|
||||||
|
|
||||||
st.name = thread_name ? thread_name : "";
|
st.name = thread_name ? thread_name : "";
|
||||||
|
if(stack == 0)
|
||||||
|
{
|
||||||
|
st.raw = false;
|
||||||
st.thread.reset(new std::thread(&safe_thread::thread_worker, this, f, thread_name, addr));
|
st.thread.reset(new std::thread(&safe_thread::thread_worker, this, f, thread_name, addr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// st.thread.reset(new std::thread(std::thread(&safe_thread::thread_worker, this, f, thread_name, addr), std::move(stack)));
|
||||||
|
LPCRAWTHRD param = new CRAWTHRD;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
param->obj = this;
|
||||||
|
param->func = f;
|
||||||
|
param->name = thread_name;
|
||||||
|
param->addr = addr;
|
||||||
|
|
||||||
|
#if OS_WIN
|
||||||
|
st.thread_raw = CreateThread(NULL, stack, &safe_thread::raw_thread, param, 0, nullptr);
|
||||||
|
if(!st.thread_raw)
|
||||||
|
err = GetLastError();
|
||||||
|
#else
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setstacksize(&attr, stack);
|
||||||
|
|
||||||
|
st.raw = true;
|
||||||
|
err = pthread_create(&st.thread_raw, &attr, &safe_thread::raw_thread, param);
|
||||||
|
if(err)
|
||||||
|
err = errno;
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
#endif
|
||||||
|
if(err)
|
||||||
|
{
|
||||||
|
delete param;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
SIMPLE_LOCK(lock_);
|
SIMPLE_LOCK(lock_);
|
||||||
threads_.push_back(st);
|
threads_.push_back(st);
|
||||||
|
@ -2242,9 +2612,21 @@ int safe_thread::stop(const char* thread_name)
|
||||||
for(int i = 0; i < threads_.size(); ++i)
|
for(int i = 0; i < threads_.size(); ++i)
|
||||||
{
|
{
|
||||||
if(!thread_name || threads_[i].name == thread_name)
|
if(!thread_name || threads_[i].name == thread_name)
|
||||||
|
{
|
||||||
|
if(threads_[i].raw)
|
||||||
|
{
|
||||||
|
#if OS_WIN
|
||||||
|
WaitForSingleObject(threads_[i].thread_raw, INFINITE);
|
||||||
|
CloseHandle(threads_[i].thread_raw);
|
||||||
|
#else
|
||||||
|
pthread_join(threads_[i].thread_raw, nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(threads_[i].thread.get() && threads_[i].thread->joinable())
|
if(threads_[i].thread.get() && threads_[i].thread->joinable())
|
||||||
threads_[i].thread->join();
|
threads_[i].thread->join();
|
||||||
|
}
|
||||||
threads_.erase(threads_.begin() + i);
|
threads_.erase(threads_.begin() + i);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if(thread_name)
|
if(thread_name)
|
||||||
|
@ -2256,3 +2638,146 @@ int safe_thread::stop(const char* thread_name)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// safe_file
|
||||||
|
safe_file::safe_file(const char* path)
|
||||||
|
{
|
||||||
|
set_file_path(path);
|
||||||
|
}
|
||||||
|
safe_file::~safe_file()
|
||||||
|
{}
|
||||||
|
|
||||||
|
uint32_t safe_file::checksum(const void* data, size_t bytes, uint32_t prev)
|
||||||
|
{
|
||||||
|
uint32_t chk = prev, mask[] = {0, 0x0ff, 0x0ffff, 0x0ffffff};
|
||||||
|
const uint32_t *d = (const uint32_t*)data;
|
||||||
|
|
||||||
|
for(int i = 0; i < bytes / 4; ++i)
|
||||||
|
chk ^= *d++;
|
||||||
|
chk ^= *d & mask[bytes % 4];
|
||||||
|
|
||||||
|
return chk;
|
||||||
|
}
|
||||||
|
std::string safe_file::load_with_check(const char* file, bool ignore_lost)
|
||||||
|
{
|
||||||
|
FILE* src = fopen(file, "rb");
|
||||||
|
std::string cont("");
|
||||||
|
|
||||||
|
if(src)
|
||||||
|
{
|
||||||
|
long l = 0;
|
||||||
|
|
||||||
|
fseek(src, 0, SEEK_END);
|
||||||
|
l = ftell(src);
|
||||||
|
fseek(src, 0, SEEK_SET);
|
||||||
|
if(l > sizeof(SFHEAD))
|
||||||
|
{
|
||||||
|
SFHEAD head;
|
||||||
|
fread(&head, 1, sizeof(head), src);
|
||||||
|
if(head.len == l - sizeof(head))
|
||||||
|
{
|
||||||
|
char buf[256] = {0};
|
||||||
|
int r = fread(buf, 1, sizeof(buf), src);
|
||||||
|
while(r > 0)
|
||||||
|
{
|
||||||
|
cont += std::string(buf, r);
|
||||||
|
r = fread(buf, 1, sizeof(buf), src);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t chk = checksum(&head, sizeof(head));
|
||||||
|
|
||||||
|
chk = checksum(cont.c_str(), cont.length(), chk);
|
||||||
|
if(chk)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Checksum(%08x) of safe_file(%s) failed!\n", chk, file);
|
||||||
|
cont = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iotimes_ = head.iotimes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "safe_file(%s) length(%d) is mismatched(%d)!\n", file, (int)l, head.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "safe_file(%s) length(%d) is too small!\n", file, (int)l);
|
||||||
|
}
|
||||||
|
fclose(src);
|
||||||
|
}
|
||||||
|
else if(!ignore_lost)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "open safe_file(%s) failed: %d(%s).\n", file, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void safe_file::set_file_path(const char* path)
|
||||||
|
{
|
||||||
|
path_ = path ? path : "";
|
||||||
|
iotimes_ = 0;
|
||||||
|
}
|
||||||
|
std::string safe_file::load(void)
|
||||||
|
{
|
||||||
|
std::string cont(load_with_check((path_ + tmp_appendix_).c_str(), true));
|
||||||
|
|
||||||
|
if(cont.empty())
|
||||||
|
cont = load_with_check(path_.c_str(), false);
|
||||||
|
|
||||||
|
return std::move(cont);
|
||||||
|
}
|
||||||
|
int safe_file::save(const void* data, uint16_t bytes)
|
||||||
|
{
|
||||||
|
// io time ...
|
||||||
|
if(iotimes_ == 0)
|
||||||
|
{
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
SFHEAD head;
|
||||||
|
FILE *dst = nullptr;
|
||||||
|
|
||||||
|
head.chksum = 0;
|
||||||
|
head.iotimes = ++iotimes_;
|
||||||
|
head.len = bytes;
|
||||||
|
head.time = time(nullptr);
|
||||||
|
head.chksum = checksum(&head, sizeof(head));
|
||||||
|
head.chksum = checksum(data, bytes, head.chksum);
|
||||||
|
|
||||||
|
dst = fopen((path_ + tmp_appendix_).c_str(), "wb");
|
||||||
|
if(!dst)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
fwrite(&head, 1, sizeof(head), dst);
|
||||||
|
fwrite(data, 1, bytes, dst);
|
||||||
|
fclose(dst);
|
||||||
|
|
||||||
|
return rename((path_ + tmp_appendix_).c_str(), path_.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// exception_ex
|
||||||
|
exception_ex::exception_ex() : what_("exception_ex")
|
||||||
|
{}
|
||||||
|
exception_ex::exception_ex(const char* msg) : what_(msg ? msg : "")
|
||||||
|
{}
|
||||||
|
exception_ex::exception_ex(const exception_ex& r) : what_(r.what_)
|
||||||
|
{}
|
||||||
|
exception_ex::~exception_ex()
|
||||||
|
{}
|
||||||
|
|
||||||
|
const char* exception_ex::what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
return what_.c_str();
|
||||||
|
}
|
||||||
|
void exception_ex::set_info(const char* info)
|
||||||
|
{
|
||||||
|
what_ = info ? info : "";
|
||||||
|
}
|
||||||
|
|
118
sdk/base/utils.h
118
sdk/base/utils.h
|
@ -37,6 +37,43 @@ namespace utils
|
||||||
std::string utf82ansi(const char* utf8);
|
std::string utf82ansi(const char* utf8);
|
||||||
std::string ansi2utf8(const char* ansi);
|
std::string ansi2utf8(const char* ansi);
|
||||||
|
|
||||||
|
// Function: parse ONE character from a utf8 string
|
||||||
|
//
|
||||||
|
// Parameters: str - [in]: head of utf8 string
|
||||||
|
//
|
||||||
|
// [out]: beginning of the next character if success or no changes on failure
|
||||||
|
//
|
||||||
|
// ch - to receive the character, at least 8 bytes
|
||||||
|
//
|
||||||
|
// Return: 0 - success
|
||||||
|
// EINVAL - invalid utf8 string
|
||||||
|
// ENODATA - need more data
|
||||||
|
int parse_utf8_char(const char*& str, char ch[8]);
|
||||||
|
|
||||||
|
// Function: transfere from utf16 to utf8
|
||||||
|
//
|
||||||
|
// Parameters: in - [in]: head of utf16 beginning
|
||||||
|
//
|
||||||
|
// [out]: beginning of the next character if success or no changes on failure
|
||||||
|
// ch - to receive the character, at least 8 bytes
|
||||||
|
//
|
||||||
|
// Return: 0 - success
|
||||||
|
// EINVAL - invalid utf8 string
|
||||||
|
// ENODATA - need more data
|
||||||
|
int utf16_2_8(unsigned short* &in, char ch[8]);
|
||||||
|
|
||||||
|
// Function: transfere from utf8 to utf16
|
||||||
|
//
|
||||||
|
// Parameters: in - [in]: head of utf8 beginning
|
||||||
|
//
|
||||||
|
// [out]: beginning of the next character if success or no changes on failure
|
||||||
|
// ch - to receive the character
|
||||||
|
//
|
||||||
|
// Return: 0 - success
|
||||||
|
// EINVAL - invalid utf8 string
|
||||||
|
int utf8_2_16(uint8_t* &in, uint16_t& ch);
|
||||||
|
int utf8_2_web(uint8_t* &in, std::string& web); // convert 'E5 A5 BD' to '\u597D'
|
||||||
|
|
||||||
std::string get_command_result(const char* cmd, int len = -1, int *err = nullptr);
|
std::string get_command_result(const char* cmd, int len = -1, int *err = nullptr);
|
||||||
std::string get_local_data_path(void);
|
std::string get_local_data_path(void);
|
||||||
std::string temporary_path(void);
|
std::string temporary_path(void);
|
||||||
|
@ -54,6 +91,8 @@ namespace utils
|
||||||
const char* to_lower(std::string& str); // return str.c_str()
|
const char* to_lower(std::string& str); // return str.c_str()
|
||||||
const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str()
|
const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str()
|
||||||
|
|
||||||
|
int get_stack_size(void);
|
||||||
|
|
||||||
bool from_hex_string(const char* hex, uint8_t* val);
|
bool from_hex_string(const char* hex, uint8_t* val);
|
||||||
bool from_hex_string(const char* hex, uint16_t* val);
|
bool from_hex_string(const char* hex, uint16_t* val);
|
||||||
bool from_hex_string(const char* hex, uint32_t* val);
|
bool from_hex_string(const char* hex, uint32_t* val);
|
||||||
|
@ -65,6 +104,7 @@ namespace utils
|
||||||
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
|
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
|
||||||
int move_file(const char* from, const char* to);
|
int move_file(const char* from, const char* to);
|
||||||
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
|
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
|
||||||
|
int get_file_time(const char* file, uint64_t* born, uint64_t* modify, uint64_t* last_access); // all time are both in seconds from 1970-01-01 00:00:00
|
||||||
|
|
||||||
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid = -1);
|
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid = -1);
|
||||||
void print_memory_usage(const char* tips, bool to_log_file);
|
void print_memory_usage(const char* tips, bool to_log_file);
|
||||||
|
@ -73,6 +113,7 @@ namespace utils
|
||||||
|
|
||||||
// return logging file path if 'type' was LOG_TYPE_FILE
|
// return logging file path if 'type' was LOG_TYPE_FILE
|
||||||
std::string init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
|
std::string init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
|
||||||
|
void set_log_file_max_size(int size = SIZE_MB(10));
|
||||||
void uninit(void);
|
void uninit(void);
|
||||||
void log_info(const char* info, int level = LOG_LEVEL_ALL);
|
void log_info(const char* info, int level = LOG_LEVEL_ALL);
|
||||||
void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ...
|
void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ...
|
||||||
|
@ -88,6 +129,7 @@ namespace utils
|
||||||
// bitmap header ...
|
// bitmap header ...
|
||||||
std::string bitmap_info_header(int pixel_w, int pixel_h, int bpp, int dpix, int dpiy = 0); // return BITMPINFOHEADER + pallete if need. dpiy same as dpix if was ZERO
|
std::string bitmap_info_header(int pixel_w, int pixel_h, int bpp, int dpix, int dpiy = 0); // return BITMPINFOHEADER + pallete if need. dpiy same as dpix if was ZERO
|
||||||
std::string bitmap_file_header(BITMAPINFOHEADER *lpbi); // return BITMAPFILEHEADER
|
std::string bitmap_file_header(BITMAPINFOHEADER *lpbi); // return BITMAPFILEHEADER
|
||||||
|
int save_bitmap(const char* file, int w, int h, int bpp, int dpix, int dpiy, void* bits);
|
||||||
|
|
||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
// Function: pump message recycle (GetMessageW)
|
// Function: pump message recycle (GetMessageW)
|
||||||
|
@ -256,6 +298,10 @@ public:
|
||||||
{
|
{
|
||||||
return obj_;
|
return obj_;
|
||||||
}
|
}
|
||||||
|
T* get(void)
|
||||||
|
{
|
||||||
|
return obj_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// time utility
|
// time utility
|
||||||
|
@ -289,6 +335,7 @@ public:
|
||||||
static uint32_t page_size;
|
static uint32_t page_size;
|
||||||
static uint32_t page_map_size;
|
static uint32_t page_map_size;
|
||||||
static uint32_t cluster_size;
|
static uint32_t cluster_size;
|
||||||
|
static uint32_t stack_size;
|
||||||
static uint32_t gray_pallete[256];
|
static uint32_t gray_pallete[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -435,8 +482,10 @@ class safe_thread
|
||||||
{
|
{
|
||||||
typedef struct _safe_thrd
|
typedef struct _safe_thrd
|
||||||
{
|
{
|
||||||
|
bool raw;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::shared_ptr<std::thread> thread;
|
std::shared_ptr<std::thread> thread; // valid when !raw
|
||||||
|
pthread_t thread_raw; // valid when raw
|
||||||
}SAFETHRD;
|
}SAFETHRD;
|
||||||
volatile bool run_ = true;
|
volatile bool run_ = true;
|
||||||
MUTEX lock_;
|
MUTEX lock_;
|
||||||
|
@ -448,12 +497,77 @@ class safe_thread
|
||||||
void thread_worker(std::function<void(void)> func, std::string name, void* addr);
|
void thread_worker(std::function<void(void)> func, std::string name, void* addr);
|
||||||
void thread_notify_exception(void);
|
void thread_notify_exception(void);
|
||||||
|
|
||||||
|
typedef struct _cr_raw_thread
|
||||||
|
{
|
||||||
|
safe_thread* obj;
|
||||||
|
std::function<void(void)> func;
|
||||||
|
std::string name;
|
||||||
|
void* addr;
|
||||||
|
}CRAWTHRD, *LPCRAWTHRD;
|
||||||
|
static
|
||||||
|
#if OS_WIN
|
||||||
|
DWORD WINAPI
|
||||||
|
#else
|
||||||
|
void*
|
||||||
|
#endif
|
||||||
|
raw_thread(void* lp);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
safe_thread(void);
|
safe_thread(void);
|
||||||
~safe_thread();
|
~safe_thread();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_exception_handler(std::function<void(const char*)> on_exception = std::function<void(const char*)>());
|
void set_exception_handler(std::function<void(const char*)> on_exception = std::function<void(const char*)>());
|
||||||
int start(std::function<void(void)> f, const char* thread_name, void* addr = nullptr);
|
int start(std::function<void(void)> f, std::size_t stack = 0, const char* thread_name = nullptr, void* addr = nullptr);
|
||||||
int stop(const char* thread_name);
|
int stop(const char* thread_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Purpose: safe file ensure the integrity of small data files
|
||||||
|
//
|
||||||
|
// Format: (uint16_t)raw data len + (uint32_t)checksum + raw data
|
||||||
|
//
|
||||||
|
// Flow: when save, write into file 'name.new' first, and rename to 'name' at last
|
||||||
|
// when read, check 'name.new' first, and open name if '.new' not exists
|
||||||
|
class safe_file
|
||||||
|
{
|
||||||
|
typedef struct _sf_head // ensure this struct size be multiple of size uint32_t
|
||||||
|
{
|
||||||
|
uint32_t chksum;
|
||||||
|
uint32_t time;
|
||||||
|
uint64_t len : 16;
|
||||||
|
uint64_t iotimes : 48;
|
||||||
|
}SFHEAD, *LPSFHEAD;
|
||||||
|
|
||||||
|
const std::string tmp_appendix_ = ".new";
|
||||||
|
std::string path_;
|
||||||
|
uint64_t iotimes_ = 0;
|
||||||
|
|
||||||
|
uint32_t checksum(const void* data, size_t bytes, uint32_t prev = 0);
|
||||||
|
std::string load_with_check(const char* file, bool ignore_lost);
|
||||||
|
|
||||||
|
public:
|
||||||
|
safe_file(const char* path);
|
||||||
|
~safe_file();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_file_path(const char* path);
|
||||||
|
std::string load(void);
|
||||||
|
int save(const void* data, uint16_t bytes);
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
class exception_ex : public std::exception
|
||||||
|
{
|
||||||
|
std::string what_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
exception_ex();
|
||||||
|
exception_ex(const char* msg);
|
||||||
|
exception_ex(const exception_ex& r);
|
||||||
|
~exception_ex();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual const char*
|
||||||
|
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT override;
|
||||||
|
void set_info(const char* info);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include "words.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define WORDS_AND_ID_IMPL(def, str) \
|
||||||
|
const char* def = str; \
|
||||||
|
const int ID_##def = __LINE__;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_COLOR_COLOR, "\345\275\251\350\211\262");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_COLOR_GRAY, "\347\201\260\345\272\246");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_PAPER_ORIGIN_SIZE, "\345\214\271\351\205\215\345\216\237\345\247\213\345\260\272\345\257\270");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_PAPER_MAX_SIZE_CROP, "\346\234\200\345\244\247\346\211\253\346\217\217\345\260\272\345\257\270\350\207\252\345\212\250\350\243\201\345\210\207");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_FORBIDDEN, "\347\246\201\347\224\250");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_SCAN_CONTINUOUS, "\350\277\236\347\273\255\346\211\253\346\217\217");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_FILLBG_CONVEX, "\345\207\270\345\244\232\350\276\271\345\275\242");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_WELCOME, "\346\254\242\350\277\216");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SELECTED, "\342\210\232");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_RETURN, "\350\277\224\345\233\236\344\270\212\347\272\247\350\217\234\345\215\225");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SEPARATE_STRENGTH, "\345\210\206\347\272\270\345\274\272\345\272\246");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_LOW, "\344\275\216");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_MID, "\344\270\255");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_HIGH, "\351\253\230");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_POWER, "\344\274\221\347\234\240\346\227\266\351\227\264");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_NONE, "\344\270\215\344\274\221\347\234\240");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_NOW, "\347\253\213\345\215\263\344\274\221\347\234\240");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_5_MIN, "5min");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_10_MIN, "10min");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_20_MIN, "20min");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_30_MIN, "30min");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_1_HOUR, "1h");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_2_HOUR, "2h");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SLEEP_4_HOUR, "4h");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_LIFTER_POS, "\345\215\207\351\231\215\345\217\260\344\275\215\347\275\256");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_COUNT_MODE, "\350\256\241\346\225\260\346\250\241\345\274\217");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_MANUAL_MODE, "\346\211\213\345\212\250\346\250\241\345\274\217");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_CLEAR_PASSWAY, "\346\270\205\347\220\206\347\272\270\351\201\223");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_HISTORY_COUNT, "\345\216\206\345\217\262\345\274\240\346\225\260");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_ROLLER_COUNT, "\346\273\232\350\275\264\345\274\240\346\225\260");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_RESET_ROLLOER_CNT, "\346\270\205\351\231\244\346\273\232\350\275\264\345\274\240\346\225\260");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_ADJUST_TIME, "\350\260\203\346\225\264\347\263\273\347\273\237\346\227\266\351\227\264");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_ADJUST_HOUR, "\346\227\266\351\222\237");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_ADJUST_MINUTE, "\345\210\206\351\222\237");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_SHUTDOWN, "\345\205\263\346\234\272");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_YES, "\347\241\256\345\256\232");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_MENU_NO, "\345\217\226\346\266\210");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_FUNCTION_COUNT, "\345\274\240\346\225\260\357\274\232");
|
||||||
|
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_READY, "\345\260\261\347\273\252");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNING_NORMAL, "\346\255\243\345\234\250\346\211\253\346\217\217\342\200\246");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNING_COUNT, "\346\255\243\345\234\250\350\256\241\346\225\260\346\211\253\346\217\217\342\200\246");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_TOTAL, "\346\200\273\357\274\232");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_NO_PAPER, "\346\227\240\347\272\270");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_COVER_OPEN, "\347\233\226\346\235\277\346\211\223\345\274\200");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_FEED_ERR, "\346\220\223\347\272\270\345\244\261\350\264\245");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_DOUBLE_FEED, "\346\243\200\346\265\213\345\210\260\345\217\214\345\274\240");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_STAPLE, "\346\243\200\346\265\213\345\210\260\351\222\211\344\271\246\351\222\211");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_ASKEW, "\347\272\270\345\274\240\346\255\252\346\226\234");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_CIS_TIMEOUT, "\345\217\226\345\233\276\350\266\205\346\227\266");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_JAMMED, "\345\215\241\347\272\270");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_CAPTURE_FAILED, "\351\207\207\345\233\276\345\244\261\350\264\245");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_CIS_OUT_OF_MEM, "\347\274\223\345\206\262\345\214\272\350\200\227\345\260\275");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_001, "\347\241\254\344\273\266\351\224\231\350\257\257001");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_002, "\347\241\254\344\273\266\351\224\231\350\257\257002");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_003, "\347\241\254\344\273\266\351\224\231\350\257\257003");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNER_CONN, "\346\211\253\346\217\217\347\250\213\345\272\217\345\267\262\351\200\200\345\207\272");
|
||||||
|
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNER_CONN_1, "\346\211\253\346\217\217\347\250\213\345\272\217\345\267\262\350\277\220\350\241\214");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
#define RETURN_ID_STR(val, def) \
|
||||||
|
if(val == ID_##def) \
|
||||||
|
return def;
|
||||||
|
|
||||||
|
const char* words_from_id(int id)
|
||||||
|
{
|
||||||
|
RETURN_ID_STR(id, WORDS_COLOR_COLOR);
|
||||||
|
RETURN_ID_STR(id, WORDS_COLOR_GRAY);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_PAPER_ORIGIN_SIZE);
|
||||||
|
RETURN_ID_STR(id, WORDS_PAPER_MAX_SIZE_CROP);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_FORBIDDEN);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_SCAN_CONTINUOUS);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_FILLBG_CONVEX);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_WELCOME);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SELECTED);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_RETURN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SEPARATE_STRENGTH);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_LOW);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_MID);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_HIGH);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_POWER);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_NONE);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_NOW);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_5_MIN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_10_MIN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_20_MIN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_30_MIN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_1_HOUR);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_2_HOUR);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SLEEP_4_HOUR);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_LIFTER_POS);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_COUNT_MODE);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_MANUAL_MODE);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_CLEAR_PASSWAY);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_HISTORY_COUNT);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_ROLLER_COUNT);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_RESET_ROLLOER_CNT);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_SHUTDOWN);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_YES);
|
||||||
|
RETURN_ID_STR(id, WORDS_MENU_NO);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_FUNCTION_COUNT);
|
||||||
|
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_READY);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_SCANNING_NORMAL);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_SCANNING_COUNT);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_TOTAL);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_NO_PAPER);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_COVER_OPEN);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_FEED_ERR);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_DOUBLE_FEED);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_STAPLE);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_ASKEW);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_CIS_TIMEOUT);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_JAMMED);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_CAPTURE_FAILED);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_CIS_OUT_OF_MEM);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_001);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_002);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_003);
|
||||||
|
RETURN_ID_STR(id, WORDS_STATUS_SCANNER_CONN);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
|
@ -3,14 +3,92 @@
|
||||||
// Date: 2024-01-24
|
// Date: 2024-01-24
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define WORDS_COLOR_COLOR "\345\275\251\350\211\262"
|
#define WORDS_AND_ID_DECL(def) \
|
||||||
#define WORDS_COLOR_GRAY "\347\201\260\345\272\246"
|
extern const char* def; \
|
||||||
|
extern const int ID_##def;
|
||||||
|
|
||||||
#define WORDS_PAPER_ORIGIN_SIZE "\345\214\271\351\205\215\345\216\237\345\247\213\345\260\272\345\257\270"
|
|
||||||
#define WORDS_PAPER_MAX_SIZE_CROP "\346\234\200\345\244\247\346\211\253\346\217\217\345\260\272\345\257\270\350\207\252\345\212\250\350\243\201\345\210\207"
|
|
||||||
|
|
||||||
#define WORDS_FORBIDDEN "\347\246\201\347\224\250"
|
#define WORDS_STR(tail) WORDS_##tail
|
||||||
|
#define WORDS_ID(tail) ID_WORDS_##tail
|
||||||
|
#define MENU_WORDS_STR(tail) WORDS_MENU_##tail
|
||||||
|
#define MENU_WORDS_ID(tail) ID_WORDS_MENU_##tail
|
||||||
|
#define STATUS_WORDS_STR(tail) WORDS_STATUS_##tail
|
||||||
|
#define STATUS_WORDS_ID(tail) ID_WORDS_STATUS_##tail
|
||||||
|
|
||||||
#define WORDS_SCAN_CONTINUOUS "\350\277\236\347\273\255\346\211\253\346\217\217"
|
|
||||||
|
|
||||||
#define WORDS_FILLBG_CONVEX "\345\207\270\345\244\232\350\276\271\345\275\242"
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
const char* words_from_id(int id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
WORDS_AND_ID_DECL(WORDS_COLOR_COLOR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_COLOR_GRAY);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_PAPER_ORIGIN_SIZE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_PAPER_MAX_SIZE_CROP);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_FORBIDDEN);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_SCAN_CONTINUOUS);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_FILLBG_CONVEX);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_WELCOME);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SELECTED);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_RETURN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SEPARATE_STRENGTH);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_LOW);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_MID);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_HIGH);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_POWER);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_NONE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_NOW);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_5_MIN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_10_MIN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_20_MIN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_30_MIN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_1_HOUR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_2_HOUR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SLEEP_4_HOUR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_LIFTER_POS);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_COUNT_MODE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_MANUAL_MODE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_CLEAR_PASSWAY);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_HISTORY_COUNT);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_ROLLER_COUNT);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_RESET_ROLLOER_CNT);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_ADJUST_TIME);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_ADJUST_HOUR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_ADJUST_MINUTE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_SHUTDOWN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_YES);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_MENU_NO);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_FUNCTION_COUNT);
|
||||||
|
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_READY);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_SCANNING_NORMAL);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_SCANNING_COUNT);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_TOTAL);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_NO_PAPER);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_COVER_OPEN);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_FEED_ERR);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_DOUBLE_FEED);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_STAPLE);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_ASKEW);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_CIS_TIMEOUT);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_JAMMED);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_CAPTURE_FAILED);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_CIS_OUT_OF_MEM);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_001);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_002);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_003);
|
||||||
|
WORDS_AND_ID_DECL(WORDS_STATUS_SCANNER_CONN);
|
|
@ -794,6 +794,7 @@ bool device_option::parse_simple_logic_expression(gb_json* root, const char* exp
|
||||||
{
|
{
|
||||||
v = std::string(next, tag - next);
|
v = std::string(next, tag - next);
|
||||||
calc.val2 = device_option::from_text_value(n.c_str(), v.c_str());
|
calc.val2 = device_option::from_text_value(n.c_str(), v.c_str());
|
||||||
|
ret = device_option::get_between(n.c_str(), &calc.compare);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue