/*! \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 . */ #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() << entry); } bool send(PIVector 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 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 & 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