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;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* packet parameter keeper, parameter of corresponding packet
*/
# 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 ;
2023-12-02 02:15:44 +00:00
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 ) ;
2023-12-02 02:15:44 +00:00
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 ) ;
2023-12-02 02:15:44 +00:00
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 ) ;
2023-12-16 07:27:40 +00:00
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-12 01:36:06 +00:00
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 ;
2023-12-02 02:15:44 +00:00
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 :
~ mem_holder ( ) ;
// 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 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 ;
2023-12-02 02:15:44 +00:00
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
# define BEFORE_DESTROY_PARAM dyn_mem* mem, void* param
# 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 ) ;
2023-12-12 01:36:06 +00:00
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 ( ) ;
void * param_ = nullptr ;
public :
dyn_mem_shared ( void * buf , size_t size , BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC ( ) , void * param = nullptr ) ;
protected :
~ dyn_mem_shared ( ) ;
} ;
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 ;
} ;
2024-01-16 09:51:34 +00:00
class image_packet : public data_source
{
dyn_mem * img_ ;
dyn_mem * head_ ;
uint32_t offset_ ;
uint32_t paper_ind_ = 0 ;
std : : string info_ ;
bool info_over_ ;
std : : string pos_str_ ;
public :
image_packet ( LPPACKIMAGE head , dyn_mem * 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 ( 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 ) ;
2024-01-16 09:51:34 +00:00
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 ) ;
} ;
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
//
2023-12-12 01:36:06 +00:00
// 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)