Files
pip/libs/main/io_utils/pifiletransfer.h
2022-12-14 14:13:52 +03:00

147 lines
4.7 KiB
C++
Raw Permalink 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
class PIP_EXPORT PIFileTransfer: public PIBaseTransfer {
PIOBJECT_SUBCLASS(PIFileTransfer, PIBaseTransfer);
public:
PIFileTransfer();
~PIFileTransfer();
enum StepType {
pft_None,
pft_Description,
pft_Data
};
struct PIP_EXPORT PFTFileInfo: public PIFile::FileInfo {
PFTFileInfo(const PIFile::FileInfo & fi = PIFile::FileInfo()): PIFile::FileInfo(fi) {}
PIString dest_path;
};
#pragma pack(push, 1)
struct PIP_EXPORT PFTHeader {
union {
struct {
char sig[3]; // PFT
uchar version;
};
uint raw_sig;
};
int step; // PacketType
int session_id;
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)
bool send(const PIFile & file);
bool send(const PIString & file);
bool send(const PIStringList & files);
bool send(PIFile::FileInfo entry) { return send(PIVector<PIFile::FileInfo>() << entry); }
bool send(PIVector<PIFile::FileInfo> entries);
void setDirectory(const PIDir & d) { dir = d; }
void setDirectory(const PIString & path) { dir.setDir(path); }
PIDir directory() const { return dir; }
bool isStarted() const { return started_; }
PIString curFile() const;
llong bytesFileAll() const { return bytes_file_all; }
llong bytesFileCur() const { return bytes_file_cur; }
const PIString * curFile_ptr() const { return &cur_file_string; }
const llong * bytesFileAll_ptr() const { return &bytes_file_all; }
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