Commit 19dbc124 authored by Guillaume Roguez's avatar Guillaume Roguez Committed by Anthony Léonard

datatransfer: API changes to not throw

GTK client uses D-Bus, so is unable to forward exceptions.
This causes crashes of daemon (unhandled exception).

This patch changes DataTransfer API to not throw (noexcept).
This is an important changes, not backware compatible,
so the API version has been modified consequently.

Change-Id: I9f2a2fe1732b2622ace16225b6e792dc15383ba1
Reviewed-by: default avatarAnthony Léonard <anthony.leonard@savoirfairelinux.com>
parent 66b2627a
...@@ -1409,59 +1409,48 @@ ...@@ -1409,59 +1409,48 @@
</arg> </arg>
</method> </method>
<method name="sendFile" tp:name-for-bindings="sendFile"> <method name="dataTransferList" tp:name-for-bindings="dataTransferList">
<tp:added version="4.2.0"/> <tp:added version="4.2.0"/>
<arg type="t" name="DataTransferId" direction="out"> <arg type="at" name="dataTransferList" direction="out"/>
</arg> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorULongLong"/>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="s" name="peer_uri" direction="in">
<tp:docstring>
RingID of request's recipient.
</tp:docstring>
</arg>
<arg type="s" name="file_path" direction="in"></arg>
<arg type="s" name="display_name" direction="in"></arg>
</method> </method>
<method name="dataTransferList" tp:name-for-bindings="dataTransferList"> <method name="sendFile" tp:name-for-bindings="sendFile">
<tp:added version="4.2.0"/> <tp:added version="4.2.0"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorULongLong"/> <arg type="u" name="dataTransferError" direction="out"/>
<arg type="at" name="DataTransferList" direction="out"> <arg type="(suuxxssss)" name="DataTransferInfo" direction="in"/>
</arg> <arg type="t" name="dataTransferId" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="DataTransferInfo"/>
</method> </method>
<method name="dataTransferInfo" tp:name-for-bindings="dataTransferInfo"> <method name="dataTransferInfo" tp:name-for-bindings="dataTransferInfo">
<tp:added version="4.2.0"/> <tp:added version="5.0.0"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="DataTransferInfo"/> <arg type="u" name="dataTransferError" direction="out"/>
<arg type="(buttssss)" name="DataTransferInfo" direction="out"> <arg type="t" name="dataTransferId" direction="in"/>
</arg> <arg type="(suuxxssss)" name="dataTransferInfo" direction="out"/>
<arg type="t" name="DataTransferId" direction="in"> <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="DataTransferInfo"/>
</arg>
</method> </method>
<method name="dataTransferBytesProgress" tp:name-for-bindings="dataTransferBytesProgress"> <method name="dataTransferBytesProgress" tp:name-for-bindings="dataTransferBytesProgress">
<tp:added version="4.2.0"/> <tp:added version="5.0.0"/>
<arg type="t" name="BytesProgress" direction="out"> <arg type="u" name="dataTransferError" direction="out"/>
</arg> <arg type="t" name="dataTransferId" direction="in"/>
<arg type="t" name="DataTransferId" direction="in"> <arg type="x" name="totalSize" direction="out"/>
</arg> <arg type="x" name="bytesProgress" direction="out"/>
</method> </method>
<method name="acceptFileTransfer" tp:name-for-bindings="acceptFileTransfer"> <method name="acceptFileTransfer" tp:name-for-bindings="acceptFileTransfer">
<tp:added version="4.2.0"/> <tp:added version="5.0.0"/>
<arg type="t" name="DataTransferId" direction="in"> <arg type="u" name="dataTransferError" direction="out"/>
</arg> <arg type="t" name="dataTransferId" direction="in"/>
<arg type="s" name="file_path" direction="in"> <arg type="s" name="filePath" direction="in"/>
</arg> <arg type="x" name="offset" direction="in"/>
<arg type="t" name="offset" direction="in">
</arg>
</method> </method>
<method name="cancelDataTransfer" tp:name-for-bindings="cancelDataTransfer"> <method name="cancelDataTransfer" tp:name-for-bindings="cancelDataTransfer">
<tp:added version="4.2.0"/> <tp:added version="5.0.0"/>
<arg type="t" name="DataTransferId" direction="in"> <arg type="u" name="dataTransferError" direction="out"/>
</arg> <arg type="t" name="dataTransferId" direction="in"/>
</method> </method>
<signal name="mediaParametersChanged" tp:name-for-bindings="mediaParametersChanged"> <signal name="mediaParametersChanged" tp:name-for-bindings="mediaParametersChanged">
......
...@@ -615,48 +615,66 @@ DBusConfigurationManager::connectivityChanged() ...@@ -615,48 +615,66 @@ DBusConfigurationManager::connectivityChanged()
} }
auto auto
DBusConfigurationManager::sendFile(const std::string& account_id, const std::string& peer_uri, DBusConfigurationManager::dataTransferList() -> decltype(DRing::dataTransferList())
const std::string& file_path, const std::string& display_name) -> decltype(DRing::sendFile(account_id, peer_uri, file_path, display_name))
{ {
return DRing::sendFile(account_id, peer_uri, file_path, display_name); return DRing::dataTransferList();
} }
DBus::Struct<bool, uint32_t, uint64_t, uint64_t, std::string, std::string, std::string, std::string> void
DBusConfigurationManager::dataTransferInfo(const DRing::DataTransferId& id) DBusConfigurationManager::sendFile(const RingDBusDataTransferInfo& in,
{ uint32_t& error,
DBus::Struct<bool, uint32_t, uint64_t, uint64_t, std::string, std::string, std::string, std::string> out; DRing::DataTransferId& id)
auto info = DRing::dataTransferInfo(id); {
out._1 = info.isOutgoing; DRing::DataTransferInfo info;
out._2 = uint32_t(info.lastEvent); info.accountId = in._1;
out._3 = info.totalSize; info.lastEvent = DRing::DataTransferEventCode(in._2);
out._4 = info.bytesProgress; info.flags = in._3;
out._5 = info.displayName; info.totalSize = in._4;
out._6 = info.path; info.bytesProgress = in._5;
out._7 = info.accountId; info.peer = in._6;
out._8 = info.peer; info.displayName = in._7;
return out; info.path = in._8;
info.mimetype = in._9;
error = uint32_t(DRing::sendFile(info, id));
} }
uint64_t void
DBusConfigurationManager::dataTransferBytesProgress(const uint64_t& id) DBusConfigurationManager::dataTransferInfo(const DRing::DataTransferId& id,
{ uint32_t& error,
return DRing::dataTransferBytesProgress(id); RingDBusDataTransferInfo& out)
{
DRing::DataTransferInfo info;
auto res = DRing::dataTransferInfo(id, info);
if (res == DRing::DataTransferError::success) {
out._1 = info.accountId;
out._2 = uint32_t(info.lastEvent);
out._3 = info.flags;
out._4 = info.totalSize;
out._5 = info.bytesProgress;
out._6 = info.peer;
out._7 = info.displayName;
out._8 = info.path;
out._9 = info.mimetype;
}
error = uint32_t(res);
} }
auto void
DBusConfigurationManager::dataTransferList() -> decltype(DRing::dataTransferList()) DBusConfigurationManager::dataTransferBytesProgress(const uint64_t& id, uint32_t& error,
int64_t& total, int64_t& progress)
{ {
return DRing::dataTransferList(); error = uint32_t(DRing::dataTransferBytesProgress(id, total, progress));
} }
void uint32_t
DBusConfigurationManager::acceptFileTransfer(const uint64_t& id, const std::string& file_path, const uint64_t& offset) DBusConfigurationManager::acceptFileTransfer(const uint64_t& id, const std::string& file_path,
const int64_t& offset)
{ {
DRing::acceptFileTransfer(id, file_path, offset); return uint32_t(DRing::acceptFileTransfer(id, file_path, offset));
} }
void uint32_t
DBusConfigurationManager::cancelDataTransfer(const uint64_t& id) DBusConfigurationManager::cancelDataTransfer(const uint64_t& id)
{ {
DRing::cancelDataTransfer(id); return uint32_t(DRing::cancelDataTransfer(id));
} }
...@@ -55,6 +55,8 @@ class DBusConfigurationManager : ...@@ -55,6 +55,8 @@ class DBusConfigurationManager :
public DBus::ObjectAdaptor public DBus::ObjectAdaptor
{ {
public: public:
using RingDBusDataTransferInfo = DBus::Struct<std::string, uint32_t, uint32_t, int64_t, int64_t, std::string, std::string, std::string, std::string>;
DBusConfigurationManager(DBus::Connection& connection); DBusConfigurationManager(DBus::Connection& connection);
// Methods // Methods
...@@ -153,13 +155,12 @@ class DBusConfigurationManager : ...@@ -153,13 +155,12 @@ class DBusConfigurationManager :
int exportAccounts(const std::vector<std::string>& accountIDs, const std::string& filepath, const std::string& password); int exportAccounts(const std::vector<std::string>& accountIDs, const std::string& filepath, const std::string& password);
int importAccounts(const std::string& archivePath, const std::string& password); int importAccounts(const std::string& archivePath, const std::string& password);
void connectivityChanged(); void connectivityChanged();
DRing::DataTransferId sendFile(const std::string& account_id, const std::string& peer_uri,
const std::string& file_path, const std::string& display_name);
DBus::Struct<bool, uint32_t, uint64_t, uint64_t, std::string, std::string, std::string, std::string> dataTransferInfo(const DRing::DataTransferId& id);
uint64_t dataTransferBytesProgress(const uint64_t& id);
std::vector<uint64_t> dataTransferList(); std::vector<uint64_t> dataTransferList();
void acceptFileTransfer(const uint64_t& id, const std::string& file_path, const uint64_t& offset); void sendFile(const RingDBusDataTransferInfo& info, uint32_t& error, DRing::DataTransferId& id);
void cancelDataTransfer(const uint64_t& id); void dataTransferInfo(const DRing::DataTransferId& id, uint32_t& error, RingDBusDataTransferInfo& info);
void dataTransferBytesProgress(const uint64_t& id, uint32_t& error, int64_t& total, int64_t& progress);
uint32_t acceptFileTransfer(const uint64_t& id, const std::string& file_path, const int64_t& offset);
uint32_t cancelDataTransfer(const uint64_t& id);
}; };
#endif // __RING_DBUSCONFIGURATIONMANAGER_H__ #endif // __RING_DBUSCONFIGURATIONMANAGER_H__
...@@ -2,7 +2,7 @@ dnl Ring - configure.ac for automake 1.9 and autoconf 2.59 ...@@ -2,7 +2,7 @@ dnl Ring - configure.ac for automake 1.9 and autoconf 2.59
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65]) AC_PREREQ([2.65])
AC_INIT([Ring Daemon],[4.3.0],[ring@gnu.org],[ring]) AC_INIT([Ring Daemon],[5.0.0],[ring@gnu.org],[ring])
AC_COPYRIGHT([[Copyright (c) Savoir-faire Linux 2004-2018]]) AC_COPYRIGHT([[Copyright (c) Savoir-faire Linux 2004-2018]])
AC_REVISION([$Revision$]) AC_REVISION([$Revision$])
......
...@@ -31,7 +31,7 @@ PROJECT_NAME = "Ring Daemon" ...@@ -31,7 +31,7 @@ PROJECT_NAME = "Ring Daemon"
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 4.3.0 PROJECT_NUMBER = 5.0.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer # for a project that appears at the top of each page and should give viewer
......
...@@ -42,45 +42,39 @@ registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWra ...@@ -42,45 +42,39 @@ registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWra
} }
std::vector<DataTransferId> std::vector<DataTransferId>
dataTransferList() dataTransferList() noexcept
{ {
return ring::Manager::instance().dataTransfers->list(); return ring::Manager::instance().dataTransfers->list();
} }
DataTransferId DataTransferError
sendFile(const std::string& account_id, sendFile(const DataTransferInfo& info, DataTransferId& id) noexcept
const std::string& peer_uri,
const std::string& file_path,
const std::string& display_name)
{ {
return ring::Manager::instance().dataTransfers->sendFile( return ring::Manager::instance().dataTransfers->sendFile(info, id);
account_id, peer_uri, file_path, display_name.empty() ? file_path : display_name);
} }
void DataTransferError
acceptFileTransfer(const DataTransferId& id, acceptFileTransfer(const DataTransferId& id, const std::string& file_path, int64_t offset) noexcept
const std::string& file_path,
std::size_t offset)
{ {
ring::Manager::instance().dataTransfers->acceptAsFile(id, file_path, offset); return ring::Manager::instance().dataTransfers->acceptAsFile(id, file_path, offset);
} }
void DataTransferError
cancelDataTransfer(const DataTransferId& id) cancelDataTransfer(const DataTransferId& id) noexcept
{ {
ring::Manager::instance().dataTransfers->cancel(id); return ring::Manager::instance().dataTransfers->cancel(id);
} }
std::streamsize DataTransferError
dataTransferBytesProgress(const DataTransferId& id) dataTransferBytesProgress(const DataTransferId& id, int64_t& total, int64_t& progress) noexcept
{ {
return ring::Manager::instance().dataTransfers->bytesProgress(id); return ring::Manager::instance().dataTransfers->bytesProgress(id, total, progress);
} }
DataTransferInfo DataTransferError
dataTransferInfo(const DataTransferId& id) dataTransferInfo(const DataTransferId& id, DataTransferInfo& info) noexcept
{ {
return ring::Manager::instance().dataTransfers->info(id); return ring::Manager::instance().dataTransfers->info(id, info);
} }
} // namespace DRing } // namespace DRing
This diff is collapsed.
...@@ -36,46 +36,32 @@ public: ...@@ -36,46 +36,32 @@ public:
DataTransferFacade(); DataTransferFacade();
~DataTransferFacade(); ~DataTransferFacade();
/// Return all known transfer id /// \see DRing::dataTransferList
std::vector<DRing::DataTransferId> list() const; std::vector<DRing::DataTransferId> list() const noexcept;
/// Send a file to a peer. /// \see DRing::sendFile
/// Open a file and send its contents over a reliable connection DRing::DataTransferError sendFile(const DRing::DataTransferInfo& info,
/// to given peer using the protocol from given account. DRing::DataTransferId& id) noexcept;
/// This method fails immediately if the file cannot be open in binary read mode,
/// if the account doesn't exist or if it doesn't support data transfer.
/// Remaining actions are operated asynchronously, so events are given by signals.
/// \return a unique data transfer identifier.
/// \except std::invalid_argument account doesn't exist or don't support data transfer.
/// \except std::ios_base::failure in case of open file errors.
DRing::DataTransferId sendFile(const std::string& account_id,
const std::string& peer_uri,
const std::string& file_path,
const std::string& display_name);
/// Accept an incoming transfer and send data into given file. /// \see DRing::acceptFileTransfer
void acceptAsFile(const DRing::DataTransferId& id, DRing::DataTransferError acceptAsFile(const DRing::DataTransferId& id,
const std::string& file_path, const std::string& file_path,
std::size_t offset); int64_t offset) noexcept;
/// Abort a transfer. /// \see DRing::cancelDataTransfer
/// The transfer id is abort and removed. The id is not longer valid after the call. DRing::DataTransferError cancel(const DRing::DataTransferId& id) noexcept;
void cancel(const DRing::DataTransferId& id);
/// \return a copy of all information about a data transfer /// \see DRing::dataTransferInfo
DRing::DataTransferInfo info(const DRing::DataTransferId& id) const; DRing::DataTransferError info(const DRing::DataTransferId& id,
DRing::DataTransferInfo& info) const noexcept;
/// \return number of bytes sent/received by a data transfer /// \see DRing::dataTransferBytesProgress
/// \note this method is fatest than info() DRing::DataTransferError bytesProgress(const DRing::DataTransferId& id, int64_t& total,
std::streamsize bytesProgress(const DRing::DataTransferId& id) const; int64_t& progress) const noexcept;
/// Create an IncomingFileTransfer object. /// Create an IncomingFileTransfer object.
/// \return a shared pointer on created Stream object, or nullptr in case of error /// \return a shared pointer on created Stream object, or nullptr in case of error
std::shared_ptr<Stream> onIncomingFileRequest(const std::string& account_id, std::shared_ptr<Stream> onIncomingFileRequest(const DRing::DataTransferInfo& info);
const std::string& peer_uri,
const std::string& display_name,
std::size_t total_size,
std::size_t offset);
private: private:
class Impl; class Impl;
......
...@@ -27,8 +27,7 @@ ...@@ -27,8 +27,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <cstdlib> // std::size_t #include <bitset>
#include <ios> // std::streamsize
namespace DRing { namespace DRing {
...@@ -36,6 +35,7 @@ using DataTransferId = uint64_t; ...@@ -36,6 +35,7 @@ using DataTransferId = uint64_t;
enum class DataTransferEventCode : uint32_t enum class DataTransferEventCode : uint32_t
{ {
invalid=0,
created, created,
unsupported, unsupported,
wait_peer_acceptance, wait_peer_acceptance,
...@@ -48,19 +48,34 @@ enum class DataTransferEventCode : uint32_t ...@@ -48,19 +48,34 @@ enum class DataTransferEventCode : uint32_t
unjoinable_peer, unjoinable_peer,
}; };
enum class DataTransferError : uint32_t
{
success=0,
unknown,
io,
invalid_argument,
};
/// Bit definition for DataTransferInfo.flags field
enum class DataTransferFlags
{
direction=0, ///< 0: outgoing, 1: incoming
};
struct DataTransferInfo struct DataTransferInfo
{ {
bool isOutgoing; ///< Outgoing or Incoming?
DataTransferEventCode lastEvent { DataTransferEventCode::created }; ///< Latest event code sent to the user
std::size_t totalSize {0} ; ///< Total number of bytes to sent/receive, 0 if not known
std::streamsize bytesProgress {0}; ///< Number of bytes sent/received
std::string displayName; ///< Human oriented transfer name
std::string path; ///< associated local file path if supported (empty, if not)
std::string accountId; ///< Identifier of the emiter/receiver account std::string accountId; ///< Identifier of the emiter/receiver account
DataTransferEventCode lastEvent { DataTransferEventCode::invalid }; ///< Latest event code sent to the user
uint32_t flags {0}; ///< Transfer global information.
int64_t totalSize {0} ; ///< Total number of bytes to sent/receive, 0 if not known
int64_t bytesProgress {0}; ///< Number of bytes sent/received
std::string peer; ///< Identifier of the remote peer (in the semantic of the associated account) std::string peer; ///< Identifier of the remote peer (in the semantic of the associated account)
std::string displayName; ///< Human oriented transfer name
std::string path; ///< associated local file path if supported (empty, if not)
std::string mimetype; ///< MimeType of transfered data (https://www.iana.org/assignments/media-types/media-types.xhtml)
}; };
std::vector<DataTransferId> dataTransferList(); std::vector<DataTransferId> dataTransferList() noexcept;
/// Asynchronously send a file to a peer using given account connection. /// Asynchronously send a file to a peer using given account connection.
/// ///
...@@ -68,24 +83,25 @@ std::vector<DataTransferId> dataTransferList(); ...@@ -68,24 +83,25 @@ std::vector<DataTransferId> dataTransferList();
/// an internal data transfer and return its identification. /// an internal data transfer and return its identification.
/// This identity code is used by signals and APIs to follow the transfer progress. /// This identity code is used by signals and APIs to follow the transfer progress.
/// ///
/// \param account_id existing account ID with file transfer support /// Following the \a info structure fields usage:
/// \param peer_uri peer address suitable for the given account /// - accountId [mandatory] existing account ID with file transfer support
/// \param file_path pathname of file to transfer /// - peer [mandatory] peer address suitable for the given account
/// \param display_name optional textual representation given to the peer when the file is proposed. /// - path [mandatory] pathname of file to transfer
/// When empty (or not given), \a file_path is used. /// - mimetype [optional] file type
/// - displayName [optional] textual representation given to the peer when the file is proposed
/// ///
/// \return DataTransferId value representing the internal transfer. /// Other fields are not used, but you must keep the default assigned value for compatibility.
/// ///
/// \exception std::invalid_argument not existing account /// \param info a DataTransferInfo structure filled with information usefull for a file transfer.
/// \exception std::ios_base::failure file opening failures /// \param[out] id data transfer identifiant if function succeed, usable with other APIs. Undefined value in case of error.
/// ///
/// \return DataTransferError::success if file is accepted for transfer, any other value in case of errors
/// \note If the account is valid but doesn't support file transfer, or if the peer is unjoignable, /// \note If the account is valid but doesn't support file transfer, or if the peer is unjoignable,
/// or at events during the transfer, the function returns a valid DataTransferId and the user /// or at any further events during the transfer, the function returns a valid DataTransferId as
/// will be signaled throught DataTransferEvent signal for such event. /// the processing is asynchronous. Application will be signaled throught DataTransferEvent signal
/// There is no reserved or special values on DataTransferId type. /// for such event. There is no reserved or special values on DataTransferId type.
/// ///
DataTransferId sendFile(const std::string& account_id, const std::string& peer_uri, DataTransferError sendFile(const DataTransferInfo& info, DataTransferId& id) noexcept;
const std::string& file_path, const std::string& display_name={});
/// Accept an incoming file transfer. /// Accept an incoming file transfer.
/// ///
...@@ -99,7 +115,11 @@ DataTransferId sendFile(const std::string& account_id, const std::string& peer_u ...@@ -99,7 +115,11 @@ DataTransferId sendFile(const std::string& account_id, const std::string& peer_u
/// \param offset used to indicate the remote side about the number of bytes already received in /// \param offset used to indicate the remote side about the number of bytes already received in
/// a previous transfer session, usefull in transfer continuation mode. /// a previous transfer session, usefull in transfer continuation mode.
/// ///
void acceptFileTransfer(const DataTransferId& id, const std::string& file_path, std::size_t offset); /// \return DataTransferError::invalid_argument if id is unknown.
/// \note unknown \a id results to a no-op call.
///
DataTransferError acceptFileTransfer(const DataTransferId& id, const std::string& file_path,
int64_t offset) noexcept;
/// Refuse or abort an outgoing or an incoming file transfer. /// Refuse or abort an outgoing or an incoming file transfer.
/// ///
...@@ -110,23 +130,32 @@ void acceptFileTransfer(const DataTransferId& id, const std::string& file_path, ...@@ -110,23 +130,32 @@ void acceptFileTransfer(const DataTransferId& id, const std::string& file_path,
/// ///
/// \param id data transfer identification value as given by a DataTransferEvent signal. /// \param id data transfer identification value as given by a DataTransferEvent signal.
/// ///
void cancelDataTransfer(const DataTransferId& id); /// \return DataTransferError::invalid_argument if id is unknown.
/// \note unknown \a id results to a no-op call.
///
DataTransferError cancelDataTransfer(const DataTransferId& id) noexcept;
/// Return some information on given data transfer. /// Return some information on given data transfer.
/// ///
/// \param id data transfer identification value as given by a DataTransferEvent signal. /// \param id data transfer identification value as given by a DataTransferEvent signal.
/// \param[out] info data transfer information.
/// ///
/// \return transfer information. /// \return DataTransferError::invalid_argument if id is unknown.
/// \note \a info structure is in undefined state in case of error.
/// ///
DataTransferInfo dataTransferInfo(const DataTransferId& id); DataTransferError dataTransferInfo(const DataTransferId& id, DataTransferInfo& info) noexcept;
/// Return the amount of sent/received bytes of an existing data transfer. /// Return the amount of sent/received bytes of an existing data transfer.
/// ///
/// \param id data transfer identification value as given by a DataTransferEvent signal. /// \param id data transfer identification value as given by a DataTransferEvent signal.
/// \param[out] total positive number of bytes to sent/received, or -1 if unknown.
/// \param[out] progress positive number of bytes already sent/received.
/// ///
/// \return number of successfuly transfered bytes. /// \return DataTransferError::success if \a total and \a progress is set with valid values.
/// DataTransferError::invalid_argument if the id is unknown.
/// ///
std::streamsize dataTransferBytesProgress(const DataTransferId& id); DataTransferError dataTransferBytesProgress(const DataTransferId& id, int64_t& total,
int64_t& progress) noexcept;
// Signal handlers registration // Signal handlers registration
void registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&); void registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&);
......
...@@ -59,11 +59,13 @@ bool ...@@ -59,11 +59,13 @@ bool
FtpServer::startNewFile() FtpServer::startNewFile()
{ {
// Request filename from client (WARNING: synchrone call!) // Request filename from client (WARNING: synchrone call!)
out_ = Manager::instance().dataTransfers->onIncomingFileRequest(accountId_, DRing::DataTransferInfo info {};
peerUri_, info.accountId = accountId_;
displayName_, info.peer = peerUri_;
fileSize_, info.displayName = displayName_;
0 /* TODO: offset */); info.totalSize = fileSize_;
info.bytesProgress = 0;
out_ = Manager::instance().dataTransfers->onIncomingFileRequest(info);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment