newtx/sdk/base/data.h

419 lines
11 KiB
C
Raw Normal View History

2023-12-01 09:17:09 +00:00
#pragma once
// Objects IO
//
// created on 2023-03-10
#include "utils.h"
#include "packet.h"
#include <string>
#include <functional>
#define CLS_PTR(cls) typedef cls* cls##_ptr;
2024-02-27 04:03:51 +00:00
#ifndef uchar
typedef unsigned char uchar;
#endif
2023-12-01 09:17:09 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* packet parameter keeper, parameter of corresponding packet
*/
2024-01-27 09:43:13 +00:00
static const uint64_t FINAL_NOTIFY = -1;
2023-12-01 09:17:09 +00:00
#define PROGRESS_NOTIFYER std::function<int(uint64_t/*total*/, uint64_t/*cur-size*/, uint32_t/*err*/, void* /*user data*/)>
class packet_data_base : public refer
{
PROGRESS_NOTIFYER progress_notify_;
void* user_data_;
protected:
2023-12-13 06:57:08 +00:00
uint32_t pack_cmd_ = 0;
uint32_t pack_id_ = 0;
uint32_t session_id_ = -1;
2023-12-01 09:17:09 +00:00
public:
packet_data_base();
protected:
virtual ~packet_data_base();
public:
void set_packet_param(uint32_t cmd, uint32_t id);
void set_session_id(uint32_t session_id);
2023-12-01 09:17:09 +00:00
int get_packet_command(void);
int get_packet_id(void);
uint32_t get_session_id(void);
2023-12-01 09:17:09 +00:00
void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER(), void* param = nullptr);
int notify_progress(uint64_t total, uint64_t cur_size, uint32_t err);
2023-12-01 09:17:09 +00:00
};
2023-12-09 10:21:05 +00:00
class file_map : public refer
{
bool read_only_ = false; //
uint32_t os_map_size_ = 0; // desired mapping size of OS
uint64_t total_ = 0; // total size of the whole file
HANDLE map_ = INVALID_HANDLE_VALUE; // handle of the map-object
std::string path_file_; // local file
uint64_t map_off_ = 0; // offset in the file of current mapping buffer
uint32_t map_size_ = 0; // size of current mapping buffer
uint32_t off_ = 0; // offset to align to os_map_size_
uint8_t* buf_ = nullptr; // current mapping buffer
void unmap(void);
public:
file_map();
protected:
~file_map();
public:
int open(const char* file, uint64_t size, bool readonly);
int close(void);
uint64_t total_size(void);
uint8_t* map(uint64_t off = 0, uint32_t* size = 0); // size - in: desired size, 0 is from off to end; out: real size
uint8_t* buffer(void);
};
2023-12-01 09:17:09 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* data_holder, used when data is also required for a certain packet
*/
class data_holder : public packet_data_base
{
public:
data_holder();
protected:
virtual ~data_holder();
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) = 0; // return error code
virtual bool is_complete(void) = 0;
virtual uint32_t get_required(void) = 0;
virtual void cancel(void);
2023-12-01 09:17:09 +00:00
};
class mem_holder : public data_holder
{
uint8_t* buf_ = nullptr;
size_t space_ = 0;
size_t wpos_ = 0;
public:
mem_holder(size_t size);
protected:
virtual ~mem_holder();
2023-12-01 09:17:09 +00:00
// data_holder
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
public:
size_t data_length(void);
uint8_t* data(void);
};
class image_holder : public mem_holder
{
PACKIMAGE head_;
public:
image_holder(LPPACKIMAGE head);
protected:
virtual ~image_holder();
public:
void set_info(LPPACKIMAGE head);
LPPACKIMAGE get_info(void);
int save_2_file(const char* root_dir, int alg_ind, const char* alg = nullptr);
};
2023-12-01 09:17:09 +00:00
class empty_holer : public data_holder
{
uint64_t size_;
uint64_t put_;
public:
empty_holer(uint64_t size);
protected:
~empty_holer();
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
};
class file_saver : public data_holder
{
uint64_t size_;
uint64_t wrote_;
std::string path_;
std::string check_;
FILE *dst_;
2023-12-09 10:21:05 +00:00
file_map *map_ = nullptr;
2023-12-01 09:17:09 +00:00
uint32_t pack_cmd_;
uint32_t pack_id_;
void close(void);
public:
file_saver(void);
protected:
~file_saver();
public:
2023-12-09 10:21:05 +00:00
int set_verify_data(const char* data, size_t len);
int open(const char* path, uint64_t size, bool in_mem = false, size_t off = 0);
2023-12-13 06:57:08 +00:00
const char* path_file(void);
2023-12-01 09:17:09 +00:00
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override;
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
virtual void cancel(void) override;
2023-12-01 09:17:09 +00:00
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* data_source, can be a memory block or STREAM object
*/
class data_source : public packet_data_base
{
uint32_t pack_cmd_;
uint32_t pack_id_;
public:
data_source();
protected:
virtual ~data_source();
public:
virtual bool is_memory_block(void) = 0;
virtual uint32_t get_rest(void) = 0;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) = 0;
// following API valid when is_memory_block() return false. return error code
virtual int fetch_data(void* buf, uint32_t* size) = 0;
};
2024-01-03 09:39:16 +00:00
// #define STAT_MEM
#define BEFORE_DESTROY_RET void
2024-02-26 09:25:02 +00:00
#define BEFORE_DESTROY_PARAM dyn_mem_shared* mem
2024-01-03 09:39:16 +00:00
#define BEFORE_DESTROY_FUNC std::function<BEFORE_DESTROY_RET(BEFORE_DESTROY_PARAM)>
2023-12-01 09:17:09 +00:00
class dyn_mem : public data_source
{
uint8_t* buf_; // data buf
size_t space_; // occupy space in bytes
size_t len_; // data length in bytes
2024-01-03 09:39:16 +00:00
#ifdef STAT_MEM
2023-12-01 09:17:09 +00:00
static MUTEX mem_lock_;
static uint64_t mem_used_bytes_;
2024-01-03 09:39:16 +00:00
#endif
2023-12-01 09:17:09 +00:00
public:
dyn_mem(size_t size);
dyn_mem(void* buf, size_t size);
2024-01-03 09:39:16 +00:00
#ifdef STAT_MEM
2023-12-01 09:17:09 +00:00
static uint64_t mem_used(void);
2024-01-03 09:39:16 +00:00
#endif
2023-12-01 09:17:09 +00:00
static dyn_mem* memory(size_t size);
protected:
2024-01-03 09:39:16 +00:00
virtual ~dyn_mem();
2023-12-01 09:17:09 +00:00
public:
uint32_t space(void);
bool set_len(size_t len);
int put(const void* data, int len);
void* detach(size_t* size); // for constructed from dyn_mem(void* buf, size_t size)
size_t used(size_t len); // used len bytes content, move following data to head and set data length, return rest data length
dyn_mem& operator+=(dyn_mem& r);
void clear_data(void);
2023-12-01 09:17:09 +00:00
// data_source
public:
virtual bool is_memory_block(void) override;
virtual uint32_t get_rest(void) override;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) override;
// following API valid when is_memory_block() return false
virtual int fetch_data(void* buf, uint32_t* size) override;
};
2024-01-03 09:39:16 +00:00
class dyn_mem_shared : public dyn_mem
{
BEFORE_DESTROY_FUNC destroy_ = BEFORE_DESTROY_FUNC();
2024-02-26 09:25:02 +00:00
void* param_[4];
2024-01-03 09:39:16 +00:00
public:
2024-02-26 09:25:02 +00:00
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC());
2024-01-03 09:39:16 +00:00
protected:
~dyn_mem_shared();
2024-02-26 09:25:02 +00:00
public:
bool set_param(void* param, int index = 0);
void* get_param(int index = 0);
2024-01-03 09:39:16 +00:00
};
2023-12-01 09:17:09 +00:00
class file_reader : public data_source
{
2023-12-09 10:21:05 +00:00
size_t len_;
size_t consume_;
FILE *src_ = nullptr;
file_map *map_ = nullptr;
2023-12-01 09:17:09 +00:00
std::string path_;
public:
file_reader();
protected:
~file_reader();
public:
2023-12-09 10:21:05 +00:00
int open(const char* file, bool in_mem, size_t off = 0);
2023-12-01 09:17:09 +00:00
int attach(FILE* f);
FILE* detach(void);
2023-12-13 06:57:08 +00:00
const char* path_file(void);
2023-12-01 09:17:09 +00:00
public:
virtual bool is_memory_block(void) override;
virtual uint32_t get_rest(void) override;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) override;
// following API valid when is_memory_block() return false
virtual int fetch_data(void* buf, uint32_t* size) override;
};
class image_packet : public data_source
{
2024-02-27 04:03:51 +00:00
// dyn_mem* img_;
std::shared_ptr<std::vector<uchar>> img_;
dyn_mem* head_;
uint32_t offset_;
uint32_t paper_ind_ = 0;
std::string info_;
bool info_over_;
std::string pos_str_;
public:
2024-02-27 04:03:51 +00:00
image_packet(LPPACKIMAGE head, std::shared_ptr<std::vector<uchar>> img, uint32_t scanid, const void* info = nullptr, size_t info_size = 0);
protected:
virtual ~image_packet();
public:
virtual bool is_memory_block(void) override;
virtual uint32_t get_rest(void) override;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) override;
// following API valid when is_memory_block() return false. return error code
virtual int fetch_data(void* buf, uint32_t* size) override;
public:
uint32_t get_paper_index(void);
};
2023-12-09 10:21:05 +00:00
2023-12-01 09:17:09 +00:00
CLS_PTR(packet_data_base);
CLS_PTR(data_holder);
CLS_PTR(mem_holder);
CLS_PTR(image_holder);
2023-12-01 09:17:09 +00:00
CLS_PTR(data_source);
CLS_PTR(dyn_mem);
2024-01-03 09:39:16 +00:00
CLS_PTR(dyn_mem_shared);
2023-12-01 09:17:09 +00:00
CLS_PTR(file_reader);
CLS_PTR(image_packet);
2023-12-01 09:17:09 +00:00
2023-12-13 06:57:08 +00:00
class dyn_mem_pool : public refer
{
volatile bool run_ = true;
dyn_mem_ptr *pool_ = nullptr;
uint32_t count_ = 0;
uint32_t unit_ = 0;
uint32_t wpos_ = 0;
uint32_t rpos_ = 0;
public:
dyn_mem_pool(uint32_t cnt, uint32_t unit);
protected:
virtual ~dyn_mem_pool();
public:
dyn_mem_ptr take(void);
void put(dyn_mem_ptr buf);
void stop(void);
uint32_t count(void);
uint32_t unit(void);
uint32_t take_pos(void);
};
2024-03-01 09:16:12 +00:00
2023-12-01 09:17:09 +00:00
// callback proto
//
// parameters: usb_functionfs_event* - the function event ptr
//
// dyn_mem_ptr - the packet buffer, read-only
//
// uint32_t* - to return how many data in bytes the handler consumed, the most high bit is to indicate whether should notify the returned packet has sent
//
// normally, the value should be sizeof(PACK_BASE) + PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet
//
// when invalid packet, suggest use the entire data
//
// packet_data_base_ptr* - return data_holder or data_source or nullptr <20><>The number of bytes required for this packet, 0 is over for this packet<65><74>
2023-12-01 09:17:09 +00:00
//
// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file'
//
// data_source: the reply content may be a large data (a large file content)
//
// return value of all routines is the reply packet, nullptr if the packet need not reply
//
// NOTE: when parameter uint32_t* and packet_data_base_ptr* both are nullptr, it is notifying the command reply packet has sent, callback should return nullptr only
//
#define FUNCTION_PROTO_PARAMETERS dyn_mem_ptr, uint32_t*, packet_data_base_ptr*
#define FUNCTION_PROTO_COMMAND_HANDLE dyn_mem_ptr(FUNCTION_PROTO_PARAMETERS)
// #define USE_THREAD_PAGED_DATA
#define REBUILD_IN_CIS_THREAD
// #define BIND_CPU
#define SENDER_PROTO data_source_ptr ptr, void* param
#define RES_CHK_PROTO int type, bool wait, int to_ms, void* param
enum cis_cb_type
{
CIS_CB_STATUS = 0, // data is status text string
CIS_CB_IMAGE, // data is image, dyn_mem_ptr is image data buffer
CIS_CB_SCAN_OVER, // dyn_mem_ptr is an uint32_t code of hardware event
};
#define CIS_IMAGE_PROTO dyn_mem_ptr data, int type, LPPACKIMAGE lpinfo