LCOV - code coverage report
Current view: top level - src - data_transfer.h (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 80.0 % 5 4
Test Date: 2026-06-13 09:18:46 Functions: 57.1 % 7 4

            Line data    Source code
       1              : /*
       2              :  *  Copyright (C) 2004-2026 Savoir-faire Linux Inc.
       3              :  *
       4              :  *  This program is free software: you can redistribute it and/or modify
       5              :  *  it under the terms of the GNU General Public License as published by
       6              :  *  the Free Software Foundation, either version 3 of the License, or
       7              :  *  (at your option) any later version.
       8              :  *
       9              :  *  This program is distributed in the hope that it will be useful,
      10              :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12              :  *  GNU General Public License for more details.
      13              :  *
      14              :  *  You should have received a copy of the GNU General Public License
      15              :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      16              :  */
      17              : #pragma once
      18              : 
      19              : #include "jami/datatransfer_interface.h"
      20              : #include "noncopyable.h"
      21              : 
      22              : #include <dhtnet/multiplexed_socket.h>
      23              : 
      24              : #include <fstream>
      25              : #include <functional>
      26              : #include <memory>
      27              : #include <string>
      28              : 
      29              : namespace jami {
      30              : 
      31              : libjami::DataTransferId generateUID(std::mt19937_64& engine);
      32              : std::string getFileId(const std::string& commitId, const std::string& tid, const std::string& displayName);
      33              : 
      34              : class Stream;
      35              : 
      36              : struct IncomingFileInfo
      37              : {
      38              :     libjami::DataTransferId id;
      39              :     std::shared_ptr<Stream> stream;
      40              : };
      41              : 
      42              : struct WaitingRequest
      43              : {
      44              :     std::string fileId;
      45              :     std::string interactionId;
      46              :     std::string sha3sum;
      47              :     std::string path;
      48              :     std::size_t totalSize;
      49           12 :     MSGPACK_DEFINE(fileId, interactionId, sha3sum, path, totalSize)
      50              : };
      51              : 
      52              : typedef std::function<void(const std::string&)> InternalCompletionCb;
      53              : typedef std::function<void()> OnFinishedCb;
      54              : 
      55              : class FileInfo
      56              : {
      57              : public:
      58              :     FileInfo(const std::shared_ptr<dhtnet::ChannelSocket>& channel,
      59              :              const std::string& fileId,
      60              :              const std::string& interactionId,
      61              :              const libjami::DataTransferInfo& info);
      62          138 :     virtual ~FileInfo() {}
      63              :     virtual void process() = 0;
      64              :     std::shared_ptr<dhtnet::ChannelSocket> channel() const { return channel_; }
      65            0 :     libjami::DataTransferInfo info() const { return info_; }
      66              :     virtual void cancel() = 0;
      67          138 :     void onFinished(std::function<void(uint32_t)>&& cb) { finishedCb_ = std::move(cb); }
      68              :     void emit(libjami::DataTransferEventCode code);
      69              : 
      70              : protected:
      71              :     std::atomic_bool isUserCancelled_ {false};
      72              :     std::string fileId_ {};
      73              :     std::string interactionId_ {};
      74              :     libjami::DataTransferInfo info_ {};
      75              :     std::shared_ptr<dhtnet::ChannelSocket> channel_ {};
      76              :     std::function<void(uint32_t)> finishedCb_ {};
      77              : };
      78              : 
      79              : class IncomingFile : public FileInfo, public std::enable_shared_from_this<IncomingFile>
      80              : {
      81              : public:
      82              :     IncomingFile(const std::shared_ptr<dhtnet::ChannelSocket>& channel,
      83              :                  const libjami::DataTransferInfo& info,
      84              :                  const std::string& fileId,
      85              :                  const std::string& interactionId,
      86              :                  const std::string& sha3Sum);
      87              :     ~IncomingFile();
      88              :     void process() override;
      89              :     void cancel() override;
      90              : 
      91              : private:
      92              :     std::mutex streamMtx_;
      93              :     std::ofstream stream_;
      94              :     std::string sha3Sum_ {};
      95              :     std::filesystem::path path_;
      96              : };
      97              : 
      98              : class OutgoingFile : public FileInfo
      99              : {
     100              : public:
     101              :     OutgoingFile(const std::shared_ptr<dhtnet::ChannelSocket>& channel,
     102              :                  const std::string& fileId,
     103              :                  const std::string& interactionId,
     104              :                  const libjami::DataTransferInfo& info,
     105              :                  size_t start = 0,
     106              :                  size_t end = 0);
     107              :     ~OutgoingFile();
     108              :     void process() override;
     109              :     void cancel() override;
     110              : 
     111              : private:
     112              :     std::ifstream stream_;
     113              :     size_t start_ {0};
     114              :     size_t end_ {0};
     115              : };
     116              : 
     117              : class TransferManager : public std::enable_shared_from_this<TransferManager>
     118              : {
     119              : public:
     120              :     TransferManager(const std::string& accountId,
     121              :                     const std::string& accountUri,
     122              :                     const std::string& to,
     123              :                     const std::mt19937_64& rand);
     124              :     ~TransferManager();
     125              : 
     126              :     /**
     127              :      * Send a file to a channel
     128              :      * @param channel       channel to use
     129              :      * @param fileId        fileId of the transfer
     130              :      * @param interactionId interactionId of the transfer
     131              :      * @param path          path of the file
     132              :      * @param start         start offset
     133              :      * @param end           end
     134              :      */
     135              :     void transferFile(const std::shared_ptr<dhtnet::ChannelSocket>& channel,
     136              :                       const std::string& fileId,
     137              :                       const std::string& interactionId,
     138              :                       const std::string& path,
     139              :                       size_t start = 0,
     140              :                       size_t end = 0,
     141              :                       OnFinishedCb onFinished = {});
     142              : 
     143              :     /**
     144              :      * Refuse a transfer
     145              :      * @param id        of the transfer
     146              :      */
     147              :     bool cancel(const std::string& fileId);
     148              : 
     149              :     /**
     150              :      * Get current transfer info
     151              :      * @param id        of the transfer
     152              :      * @param total     size
     153              :      * @param path      path of the file
     154              :      * @param progress  current progress
     155              :      * @return if found
     156              :      */
     157              :     bool info(const std::string& fileId, std::string& path, int64_t& total, int64_t& progress) const noexcept;
     158              : 
     159              :     /**
     160              :      * Inform the transfer manager that a transfer is waited (and will be automatically accepted)
     161              :      * @param id              of the transfer
     162              :      * @param interactionId   linked interaction
     163              :      * @param sha3sum         attended sha3sum
     164              :      * @param path            where the file will be downloaded
     165              :      * @param total           total size of the file
     166              :      */
     167              :     void waitForTransfer(const std::string& fileId,
     168              :                          const std::string& interactionId,
     169              :                          const std::string& sha3sum,
     170              :                          const std::string& path,
     171              :                          std::size_t total);
     172              : 
     173              :     /**
     174              :      * Handle incoming transfer
     175              :      * @param id        Related id
     176              :      * @param channel   Related channel
     177              :      * @param start     Offset in the file from which the transfer will start.
     178              :      */
     179              :     void onIncomingFileTransfer(const std::string& fileId,
     180              :                                 const std::shared_ptr<dhtnet::ChannelSocket>& channel,
     181              :                                 size_t start);
     182              : 
     183              :     /**
     184              :      * Retrieve path of a file
     185              :      * @param id
     186              :      */
     187              :     std::filesystem::path path(const std::string& fileId) const;
     188              : 
     189              :     /**
     190              :      * Retrieve waiting files
     191              :      * @return waiting list
     192              :      */
     193              :     std::vector<WaitingRequest> waitingRequests() const;
     194              :     bool isWaiting(const std::string& fileId) const;
     195              :     void onIncomingProfile(const std::shared_ptr<dhtnet::ChannelSocket>& channel, const std::string& sha3Sum = "");
     196              : 
     197              :     /**
     198              :      * @param contactId     contact's id
     199              :      * @return where profile.vcf is stored
     200              :      */
     201              :     std::filesystem::path profilePath(const std::string& contactId) const;
     202              : 
     203              : private:
     204          138 :     std::weak_ptr<TransferManager> weak() { return std::static_pointer_cast<TransferManager>(shared_from_this()); }
     205              :     NON_COPYABLE(TransferManager);
     206              :     class Impl;
     207              :     std::unique_ptr<Impl> pimpl_;
     208              : };
     209              : 
     210              : } // namespace jami
        

Generated by: LCOV version 2.0-1