Files
pip/libs/main/io_utils/pifiletransfer.h

205 lines
7.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file pifiletransfer.h
* \ingroup IO
* \~\brief
* \~english Class for send and receive files and directories via \a PIBaseTransfer
* \~russian Класс для отправки и приема файлов и папок с помощью \a PIBaseTransfer
*/
/*
PIP - Platform Independent Primitives
Class for send and receive files and directories via PIBaseTransfer
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIFILETRANSFER_H
#define PIFILETRANSFER_H
#include "pibasetransfer.h"
#include "pidir.h"
#define __PIFILETRANSFER_VERSION 2
//! \~english Class for send and receive files and directories via \a PIBaseTransfer
//! \~russian Класс для отправки и приема файлов и папок с помощью \a PIBaseTransfer
class PIP_EXPORT PIFileTransfer: public PIBaseTransfer {
PIOBJECT_SUBCLASS(PIFileTransfer, PIBaseTransfer);
public:
//! \~english Constructs empty file transfer
//! \~russian Создает пустой transfer файлов
PIFileTransfer();
//! \~english Destructor
//! \~russian Деструктор
~PIFileTransfer();
//! \~english Step type for file transfer
//! \~russian Тип шага для передачи файлов
enum StepType {
pft_None,
pft_Description,
pft_Data
};
//! \~english File information structure
//! \~russian Структура информации о файле
struct PIP_EXPORT PFTFileInfo: public PIFile::FileInfo {
//! \~english Constructor
//! \~russian Конструктор
PFTFileInfo(const PIFile::FileInfo & fi = PIFile::FileInfo()): PIFile::FileInfo(fi) {}
PIString dest_path;
};
#pragma pack(push, 1)
//! \~english File transfer header structure
//! \~russian Структура заголовка передачи файлов
struct PIP_EXPORT PFTHeader {
union {
struct {
char sig[3]; // PFT
uchar version;
};
uint raw_sig;
};
int step; // PacketType
int session_id;
//! \~english Check if signature is valid
//! \~russian Проверка валидности подписи
bool check_sig() {
if (sig[0] != sign[0] || sig[1] != sign[1] || sig[2] != sign[2] || version != __PIFILETRANSFER_VERSION) return false;
return true;
}
};
#pragma pack(pop)
//! \~english Send file
//! \~russian Отправить файл
bool send(const PIFile & file);
//! \~english Send file by path
//! \~russian Отправить файл по пути
bool send(const PIString & file);
//! \~english Send files list
//! \~russian Отправить список файлов
bool send(const PIStringList & files);
//! \~english Send file info
//! \~russian Отправить информацию о файле
bool send(PIFile::FileInfo entry) { return send(PIVector<PIFile::FileInfo>() << entry); }
//! \~english Send file info vector
//! \~russian Отправить вектор информации о файлах
bool send(PIVector<PIFile::FileInfo> entries);
//! \~english Set directory
//! \~russian Установить директорию
void setDirectory(const PIDir & d) { dir = d; }
//! \~english Set directory by path
//! \~russian Установить директорию по пути
void setDirectory(const PIString & path) { dir.setDir(path); }
//! \~english Get directory
//! \~russian Получить директорию
PIDir directory() const { return dir; }
//! \~english Check if transfer is started
//! \~russian Проверить, начата ли передача
bool isStarted() const { return started_; }
//! \~english Get current file name
//! \~russian Получить имя текущего файла
PIString curFile() const;
//! \~english Get total bytes of current file
//! \~russian Получить общее количество байт текущего файла
llong bytesFileAll() const { return bytes_file_all; }
//! \~english Get current bytes of current file
//! \~russian Получить текущие байты текущего файла
llong bytesFileCur() const { return bytes_file_cur; }
//! \~english Get pointer to current file name
//! \~russian Получить указатель на имя текущего файла
const PIString * curFile_ptr() const { return &cur_file_string; }
//! \~english Get pointer to total bytes of current file
//! \~russian Получить указатель на общее количество байт текущего файла
const llong * bytesFileAll_ptr() const { return &bytes_file_all; }
//! \~english Get pointer to current bytes of current file
//! \~russian Получить указатель на текущие байты текущего файла
const llong * bytesFileCur_ptr() const { return &bytes_file_cur; }
EVENT(receiveFilesStarted);
EVENT1(receiveFilesFinished, bool, ok);
EVENT(sendFilesStarted);
EVENT1(sendFilesFinished, bool, ok);
EVENT3(receiveFilesRequest, PIStringList, files, llong, total_bytes, bool *, ok);
private:
static const char sign[];
PIVector<PFTFileInfo> files_;
PIString cur_file_string;
llong bytes_file_all, bytes_file_cur;
PFTHeader pftheader;
PIDir dir;
PIFile work_file;
PIByteArray desc;
PIDir scan_dir;
bool started_, scanning;
PIMutex step_mutex;
bool sendFiles(const PIVector<PFTFileInfo> & files);
void processFile(int id, ullong start, PIByteArray & data);
void receivePart(Part fi, PIByteArray ba, PIByteArray pheader) override;
PIByteArray buildPacket(Part fi) override;
PIByteArray customHeader() override;
void beginReceive() override;
EVENT_HANDLER1(void, send_finished, bool, ok);
EVENT_HANDLER1(void, receive_finished, bool, ok);
};
BINARY_STREAM_WRITE(PIFileTransfer::PFTHeader) {
s << v.raw_sig << v.step << v.session_id;
return s;
}
BINARY_STREAM_READ(PIFileTransfer::PFTHeader) {
s >> v.raw_sig >> v.step >> v.session_id;
return s;
}
BINARY_STREAM_WRITE(PIFileTransfer::PFTFileInfo) {
s << v.dest_path << v.size << v.time_access << v.time_modification << v.flags << v.id_user << v.id_group << v.perm_user.raw
<< v.perm_group.raw << v.perm_other.raw;
return s;
}
BINARY_STREAM_READ(PIFileTransfer::PFTFileInfo) {
s >> v.dest_path >> v.size >> v.time_access >> v.time_modification >> v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >>
v.perm_group.raw >> v.perm_other.raw;
return s;
}
inline PICout operator<<(PICout s, const PIFileTransfer::PFTFileInfo & v) {
s.saveAndSetControls(0);
s << "FileInfo(\"" << v.dest_path << "\", " << PIString::readableSize(v.size) << ", " << v.perm_user.toString() << " "
<< v.perm_group.toString() << " " << v.perm_other.toString() << ", " << v.time_access.toString() << ", "
<< v.time_modification.toString() << ", 0x" << PICoutManipulators::Hex << v.flags << ")";
s.restoreControls();
return s;
}
#endif // PIFILETRANSFER_H