490 lines
8.5 KiB
C++
490 lines
8.5 KiB
C++
#include "data.h"
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#if defined(WIN32) || defined(_WIN64)
|
|
#else
|
|
#include <sys/fcntl.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
packet_data_base::packet_data_base() : pack_cmd_(0), pack_id_(0)
|
|
, progress_notify_(PROGRESS_NOTIFYER()), user_data_(nullptr)
|
|
{}
|
|
packet_data_base::~packet_data_base()
|
|
{}
|
|
|
|
int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err)
|
|
{
|
|
if (progress_notify_)
|
|
progress_notify_(total, cur_size, err, user_data_);
|
|
else
|
|
return ENOENT;
|
|
}
|
|
|
|
void packet_data_base::set_packet_param(uint32_t cmd, uint32_t id)
|
|
{
|
|
pack_cmd_ = cmd;
|
|
pack_id_ = id;
|
|
}
|
|
void packet_data_base::set_session_id(uint32_t session_id)
|
|
{
|
|
session_id_ = session_id;
|
|
}
|
|
int packet_data_base::get_packet_command(void)
|
|
{
|
|
return pack_cmd_;
|
|
}
|
|
int packet_data_base::get_packet_id(void)
|
|
{
|
|
return pack_id_;
|
|
}
|
|
uint32_t packet_data_base::get_session_id(void)
|
|
{
|
|
return session_id_;
|
|
}
|
|
|
|
void packet_data_base::set_progress_notify(PROGRESS_NOTIFYER notify, void* param)
|
|
{
|
|
progress_notify_ = notify;
|
|
user_data_ = param;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
data_holder::data_holder()
|
|
{}
|
|
data_holder::~data_holder()
|
|
{}
|
|
|
|
void data_holder::cancel(void)
|
|
{}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
mem_holder::mem_holder(size_t size) : space_(size)
|
|
{
|
|
buf_ = (uint8_t*)malloc(size);
|
|
if (buf_)
|
|
memset(buf_, 0, size);
|
|
}
|
|
mem_holder::~mem_holder()
|
|
{
|
|
if (buf_)
|
|
free(buf_);
|
|
buf_ = nullptr;
|
|
}
|
|
|
|
int mem_holder::put_data(const void* data, uint32_t* size)
|
|
{
|
|
if (*size > space_ - wpos_)
|
|
*size = space_ - wpos_;
|
|
|
|
memcpy(buf_ + wpos_, data, *size);
|
|
wpos_ += *size;
|
|
|
|
return 0;
|
|
}
|
|
bool mem_holder::is_complete(void)
|
|
{
|
|
return wpos_ >= space_;
|
|
}
|
|
uint32_t mem_holder::get_required(void)
|
|
{
|
|
if (wpos_ >= space_)
|
|
return 0;
|
|
else
|
|
return space_ - wpos_;
|
|
}
|
|
|
|
size_t mem_holder::data_length(void)
|
|
{
|
|
return wpos_;
|
|
}
|
|
uint8_t* mem_holder::data(void)
|
|
{
|
|
return buf_;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
empty_holer::empty_holer(uint64_t size) : size_(size), put_(0)
|
|
{}
|
|
empty_holer::~empty_holer()
|
|
{}
|
|
|
|
int empty_holer::put_data(const void* data, uint32_t* size)
|
|
{
|
|
if (*size >= size_ - put_)
|
|
{
|
|
*size -= size_ - put_;
|
|
put_ = size_;
|
|
}
|
|
else
|
|
{
|
|
put_ += *size;
|
|
}
|
|
notify_progress(size_, put_, 0);
|
|
|
|
return 0;
|
|
}
|
|
bool empty_holer::is_complete(void)
|
|
{
|
|
return size_ == put_;
|
|
}
|
|
uint32_t empty_holer::get_required(void)
|
|
{
|
|
return size_ - put_;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
file_saver::file_saver(void) : size_(0), wrote_(0), path_(""), check_(""), dst_(nullptr), pack_cmd_(0), pack_id_(0)
|
|
{}
|
|
file_saver::~file_saver()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void file_saver::close(void)
|
|
{
|
|
if(dst_)
|
|
fclose(dst_);
|
|
dst_ = nullptr;
|
|
|
|
size_ = wrote_ = pack_cmd_ = pack_id_ = 0;
|
|
path_ = check_ = "";
|
|
}
|
|
|
|
int file_saver::open(const char* path, uint64_t size, const char* check)
|
|
{
|
|
int err = 0;
|
|
|
|
close();
|
|
dst_ = fopen(path, "wb");
|
|
if(dst_)
|
|
{
|
|
unsigned long long space = 0;
|
|
|
|
err = utils::get_disk_space(path, nullptr, &space, nullptr);
|
|
if (err || space < size * 1.5)
|
|
{
|
|
fclose(dst_);
|
|
dst_ = nullptr;
|
|
remove(path);
|
|
if (err == 0)
|
|
err = ENOSPC;
|
|
}
|
|
else
|
|
{
|
|
path_ = path;
|
|
size_ = size;
|
|
check_ = check ? check : "";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = errno;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/)
|
|
{
|
|
if(!dst_)
|
|
return ENOENT;
|
|
|
|
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size,
|
|
real_w = fwrite(data, 1, w, dst_), // should handle error here !
|
|
err = 0;
|
|
|
|
*size = real_w;
|
|
wrote_ += real_w;
|
|
if(wrote_ >= size_)
|
|
{
|
|
fclose(dst_);
|
|
dst_ = nullptr;
|
|
}
|
|
else if (real_w < w) // what happens ?
|
|
{
|
|
err = ferror(dst_);
|
|
}
|
|
notify_progress(size_, wrote_, err);
|
|
|
|
return 0;
|
|
}
|
|
bool file_saver::is_complete(void)
|
|
{
|
|
return wrote_ >= size_;
|
|
}
|
|
uint32_t file_saver::get_required(void)
|
|
{
|
|
return size_ - wrote_;
|
|
}
|
|
void file_saver::cancel(void)
|
|
{
|
|
utils::to_log(LOG_LEVEL_DEBUG, "Discard receiving file (%u/%u): '%s'.\n", wrote_, size_, path_.c_str());
|
|
close();
|
|
remove(path_.c_str());
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
data_source::data_source()
|
|
{}
|
|
data_source::~data_source()
|
|
{}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// dyn_mem
|
|
uint64_t dyn_mem::mem_used_bytes_ = 0;
|
|
MUTEX dyn_mem::mem_lock_;
|
|
|
|
dyn_mem::dyn_mem(size_t size) : buf_(nullptr), len_(0), space_(ALIGN_TO(size, 16))
|
|
{
|
|
buf_ = (uint8_t*)malloc(space_);
|
|
if (buf_)
|
|
{
|
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
|
dyn_mem::mem_used_bytes_ += space_;
|
|
memset(buf_, 0, space_);
|
|
}
|
|
}
|
|
dyn_mem::dyn_mem(void* buf, size_t size) : buf_((uint8_t*)buf), space_(size), len_(size)
|
|
{
|
|
|
|
}
|
|
|
|
dyn_mem::~dyn_mem()
|
|
{
|
|
if (buf_)
|
|
{
|
|
free(buf_);
|
|
{
|
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
|
dyn_mem::mem_used_bytes_ -= space_;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint64_t dyn_mem::mem_used(void)
|
|
{
|
|
return dyn_mem::mem_used_bytes_;
|
|
}
|
|
dyn_mem_ptr dyn_mem::memory(size_t size)
|
|
{
|
|
return new dyn_mem(size);
|
|
}
|
|
|
|
uint32_t dyn_mem::space(void)
|
|
{
|
|
return space_;
|
|
}
|
|
bool dyn_mem::set_len(size_t len)
|
|
{
|
|
if (len > space_)
|
|
return false;
|
|
|
|
len_ = len;
|
|
|
|
return true;
|
|
}
|
|
int dyn_mem::put(const void* data, int len)
|
|
{
|
|
if (len + len_ > space_)
|
|
len = space_ - len;
|
|
|
|
if (len > 0)
|
|
{
|
|
memcpy(buf_ + len_, data, len);
|
|
len_ += len;
|
|
}
|
|
else
|
|
len = 0;
|
|
|
|
return len;
|
|
}
|
|
void* dyn_mem::detach(size_t* size)
|
|
{
|
|
void* buf = buf_;
|
|
|
|
if (size)
|
|
*size = space_;
|
|
space_ = len_ = 0;
|
|
buf_ = nullptr;
|
|
|
|
return buf;
|
|
}
|
|
|
|
size_t dyn_mem::used(size_t len)
|
|
{
|
|
if (len >= len_)
|
|
{
|
|
len_ = 0;
|
|
}
|
|
else if (len)
|
|
{
|
|
memcpy(buf_, buf_ + len, len_ - len);
|
|
len_ -= len;
|
|
}
|
|
|
|
return len_;
|
|
}
|
|
dyn_mem& dyn_mem::operator+=(dyn_mem& r)
|
|
{
|
|
if (len_ + r.get_rest() > space_)
|
|
{
|
|
size_t size = ALIGN_TO(len_ + r.get_rest(), 16);
|
|
uint8_t* buf = (uint8_t*)malloc(size);
|
|
memcpy(buf, buf_, len_);
|
|
free(buf_);
|
|
buf_ = buf;
|
|
{
|
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
|
dyn_mem::mem_used_bytes_ += size - space_;
|
|
}
|
|
space_ = size;
|
|
}
|
|
memcpy(buf_ + len_, r.buf_, r.get_rest());
|
|
len_ += r.get_rest();
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool dyn_mem::is_memory_block(void)
|
|
{
|
|
return true;
|
|
}
|
|
uint32_t dyn_mem::get_rest(void)
|
|
{
|
|
return len_;
|
|
}
|
|
|
|
// following API valid when is_memory_block() return true
|
|
uint8_t* dyn_mem::ptr(void)
|
|
{
|
|
return buf_;
|
|
}
|
|
|
|
// following API valid when is_memory_block() return false
|
|
int dyn_mem::fetch_data(void* buf, uint32_t* size)
|
|
{
|
|
if (*size >= len_)
|
|
{
|
|
memcpy(buf, buf_, len_);
|
|
*size = len_;
|
|
len_ = 0;
|
|
}
|
|
else
|
|
{
|
|
memcpy(buf, buf_, *size);
|
|
used(*size);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
file_reader::file_reader() : len_(0), src_(nullptr), path_(""), consume_(0)
|
|
{}
|
|
file_reader::~file_reader()
|
|
{
|
|
if(src_)
|
|
fclose(src_);
|
|
}
|
|
|
|
int file_reader::open(const char* file)
|
|
{
|
|
if(src_)
|
|
fclose(src_);
|
|
|
|
src_ = fopen(file, "rb");
|
|
if(!src_)
|
|
return errno;
|
|
|
|
FSEEK(src_, 0, SEEK_END);
|
|
len_ = FTELL(src_);
|
|
FSEEK(src_, 0, SEEK_SET);
|
|
path_ = file;
|
|
consume_ = 0;
|
|
|
|
return 0;
|
|
}
|
|
int file_reader::attach(FILE* f)
|
|
{
|
|
if (src_)
|
|
{
|
|
fclose(src_);
|
|
src_ = nullptr;
|
|
}
|
|
|
|
uint64_t cur = FTELL(f);
|
|
|
|
FSEEK(f, 0, SEEK_END);
|
|
len_ = FTELL(f);
|
|
FSEEK(f, cur, SEEK_SET);
|
|
if (len_ <= cur)
|
|
return EINVAL;
|
|
|
|
src_ = f;
|
|
len_ -= cur;
|
|
consume_ = 0;
|
|
|
|
return 0;
|
|
}
|
|
FILE* file_reader::detach(void)
|
|
{
|
|
FILE* ret = src_;
|
|
|
|
src_ = nullptr;
|
|
len_ = 0;
|
|
path_ = "";
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool file_reader::is_memory_block(void)
|
|
{
|
|
return false;
|
|
}
|
|
uint32_t file_reader::get_rest(void)
|
|
{
|
|
return len_ - consume_;
|
|
}
|
|
|
|
// following API valid when is_memory_block() return true
|
|
uint8_t* file_reader::ptr(void)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
// following API valid when is_memory_block() return false
|
|
int file_reader::fetch_data(void* buf, uint32_t* size)
|
|
{
|
|
if (!src_)
|
|
return ENODATA;
|
|
|
|
size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!!
|
|
|
|
consume_ += r;
|
|
*size = r;
|
|
if (consume_ >= len_)
|
|
{
|
|
fclose(src_);
|
|
src_ = nullptr;
|
|
}
|
|
notify_progress(len_, consume_, 0);
|
|
|
|
return 0;
|
|
}
|