transfer_sender.cpp 2.38 KB
Newer Older
1
#include <iostream>
2
#include <logging/logging.hpp>
3
#include <network/transfer_sender.hpp>
4 5 6
#include <network/message.hpp>
#include <network/message_handler.hpp>
#include <network/tls_socket.hpp>
7

8 9 10
using namespace std::string_literals;

static constexpr std::size_t CHUNK_SIZE = 262144u;
louiz’'s avatar
louiz’ committed
11

12 13
unsigned long int TransferSender::current_id = 0;

14 15
TransferSender::TransferSender(MessageHandler<TLSSocket>* client, const std::string& filename,
                               std::function<void(const TransferSender*)>&& end_callback):
16
  client(client),
17 18
  filename(filename),
  end_callback(std::move(end_callback))
19
{
20
  boost::filesystem::path file_name = FILES_TO_SEND_DIRECTORY / this->filename;
21
  this->file.open(file_name, std::ofstream::binary);
louiz’'s avatar
louiz’ committed
22

23
  this->id = std::to_string(TransferSender::current_id++);
24 25 26 27 28 29 30 31 32 33
}

TransferSender::~TransferSender()
{
  log_debug("Deleting file transfer of " << this->filename << ": " << this->id);
  this->file.close();
}

bool TransferSender::start()
{
34
  // log_debug("Starting file transfer " << this->id);
35 36 37 38 39 40 41 42 43 44 45 46
  if (this->file.good())
    {
      // get length of file:
      this->file.seekg(0, std::ios::end);
      this->length = this->file.tellg();
      this->file.seekg(0, std::ios::beg);
      std::ostringstream sid;
      sid << this->id;
      std::ostringstream slength;
      slength << this->length;
      std::string transfer_description(sid.str());
      transfer_description += "|" + this->filename + "|"  + slength.str();
47

48 49 50 51
      Message* message = new Message;
      message->set_name("TRANSFER");
      message->set_body(transfer_description.data(), transfer_description.size());
      this->client->send(message);
52 53 54 55 56 57 58 59
      return true;
    }
  log_warning("Could not open file to send: " << this->filename);
  return false;
}

void TransferSender::send_next_chunk()
{
60
  Message* message = new Message;
61

62 63
  message->body = new char[CHUNK_SIZE];
  std::streamsize read_size = this->file.readsome(message->body, CHUNK_SIZE);
64
  log_debug("Read from file: " << read_size);
65
  message->set_body_size(read_size);
66

67 68
  std::string message_name = "TRANSFER_" + this->id;
  message->set_name(message_name);
69
  if (read_size)
louiz’'s avatar
louiz’ committed
70 71 72
    {
      // this was not the last chunk, so we'll send an other one when this one is
      // successfully sent.
73
      this->client->send(message, std::bind(&TransferSender::send_next_chunk, this));
louiz’'s avatar
louiz’ committed
74
    }
75
  else
76
    this->client->send(message, [this]() { this->end_callback(this); });
77
}