transmission/libtransmission/torrent-ctor.cc

233 lines
5.9 KiB
C++

// This file Copyright © Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include "libtransmission/transmission.h"
#include "libtransmission/torrent-ctor.h"
#include "libtransmission/error.h"
#include "libtransmission/utils.h" // for tr_file_read()
using namespace std::literals;
tr_ctor::tr_ctor(tr_session* const session)
: session_{ session }
{
set_download_dir(TR_FALLBACK, session->downloadDir());
set_paused(TR_FALLBACK, session->shouldPauseAddedTorrents());
set_peer_limit(TR_FALLBACK, session->peerLimitPerTorrent());
set_should_delete_source_file(session->shouldDeleteSource());
}
bool tr_ctor::set_metainfo_from_file(std::string_view filename, tr_error* error)
{
if (std::empty(filename))
{
if (error != nullptr)
{
error->set(EINVAL, "no filename specified"sv);
}
return false;
}
if (!tr_file_read(filename, contents_, error))
{
return false;
}
torrent_filename_ = filename;
auto const contents_sv = std::string_view{ std::data(contents_), std::size(contents_) };
return metainfo_.parse_benc(contents_sv, error);
}
bool tr_ctor::save(std::string_view filename, tr_error* error) const
{
TR_ASSERT(!std::empty(filename));
if (std::empty(contents_))
{
if (error != nullptr)
{
error->set(EINVAL, "torrent ctor has no contents to save"sv);
}
return false;
}
return tr_file_save(filename, contents_, error);
}
void tr_ctor::init_torrent_priorities(tr_torrent& tor) const
{
tor.set_file_priorities(std::data(low_), std::size(low_), TR_PRI_LOW);
tor.set_file_priorities(std::data(normal_), std::size(normal_), TR_PRI_NORMAL);
tor.set_file_priorities(std::data(high_), std::size(high_), TR_PRI_HIGH);
}
void tr_ctor::init_torrent_wanted(tr_torrent& tor) const
{
tor.init_files_wanted(std::data(unwanted_), std::size(unwanted_), false);
tor.init_files_wanted(std::data(wanted_), std::size(wanted_), true);
}
// --- PUBLIC C API
tr_ctor* tr_ctorNew(tr_session* session)
{
return new tr_ctor{ session };
}
void tr_ctorFree(tr_ctor* ctor)
{
delete ctor;
}
tr_session* tr_ctorGetSession(tr_ctor const* ctor)
{
return ctor->session();
}
bool tr_ctorSetMetainfoFromFile(tr_ctor* const ctor, char const* const filename, tr_error* const error)
{
return ctor->set_metainfo_from_file(std::string_view{ filename != nullptr ? filename : "" }, error);
}
bool tr_ctorSetMetainfo(tr_ctor* const ctor, char const* const metainfo, size_t len, tr_error* const error)
{
auto const metainfo_sv = len == 0 || metainfo == nullptr ? ""sv : std::string_view{ metainfo, len };
return ctor->set_metainfo(metainfo_sv, error);
}
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* const ctor, char const* const magnet, tr_error* const error)
{
auto const magnet_sv = std::string_view{ magnet != nullptr ? magnet : "" };
return ctor->set_metainfo_from_magnet_link(magnet_sv, error);
}
char const* tr_ctorGetSourceFile(tr_ctor const* const ctor)
{
return ctor->torrent_filename().c_str();
}
void tr_ctorSetFilePriorities(
tr_ctor* const ctor,
tr_file_index_t const* const files,
tr_file_index_t const n_files,
tr_priority_t const priority)
{
ctor->set_file_priorities(files, n_files, priority);
}
void tr_ctorSetFilesWanted(tr_ctor* ctor, tr_file_index_t const* const files, tr_file_index_t const n_files, bool const wanted)
{
ctor->set_files_wanted(files, n_files, wanted);
}
void tr_ctorSetDeleteSource(tr_ctor* const ctor, bool const delete_source)
{
ctor->set_should_delete_source_file(delete_source);
}
bool tr_ctorGetDeleteSource(tr_ctor const* const ctor, bool* const setme)
{
if (ctor != nullptr)
{
if (setme != nullptr)
{
*setme = ctor->should_delete_source_file();
}
return true;
}
return false;
}
void tr_ctorSetPaused(tr_ctor* const ctor, tr_ctorMode const mode, bool const paused)
{
ctor->set_paused(mode, paused);
}
void tr_ctorSetPeerLimit(tr_ctor* const ctor, tr_ctorMode const mode, uint16_t const peer_limit)
{
ctor->set_peer_limit(mode, peer_limit);
}
void tr_ctorSetDownloadDir(tr_ctor* const ctor, tr_ctorMode const mode, char const* const dir)
{
return ctor->set_download_dir(mode, std::string_view{ dir != nullptr ? dir : "" });
}
void tr_ctorSetIncompleteDir(tr_ctor* const ctor, char const* const dir)
{
return ctor->set_incomplete_dir(std::string_view{ dir != nullptr ? dir : "" });
}
bool tr_ctorGetPeerLimit(tr_ctor const* const ctor, tr_ctorMode const mode, uint16_t* const setme)
{
if (auto const val = ctor->peer_limit(mode); val)
{
if (setme != nullptr)
{
*setme = *val;
}
return true;
}
return false;
}
bool tr_ctorGetPaused(tr_ctor const* const ctor, tr_ctorMode const mode, bool* const setme)
{
if (auto const val = ctor->paused(mode); val)
{
if (setme != nullptr)
{
*setme = *val;
}
return true;
}
return false;
}
bool tr_ctorGetDownloadDir(tr_ctor const* const ctor, tr_ctorMode const mode, char const** setme)
{
if (auto const& val = ctor->download_dir(mode); !std::empty(val))
{
if (setme != nullptr)
{
*setme = val.c_str();
}
return true;
}
return false;
}
bool tr_ctorGetIncompleteDir(tr_ctor const* const ctor, char const** setme)
{
if (auto const& val = ctor->incomplete_dir(); !std::empty(val))
{
if (setme != nullptr)
{
*setme = val.c_str();
}
return true;
}
return false;
}
tr_torrent_metainfo const* tr_ctorGetMetainfo(tr_ctor const* const ctor)
{
auto const& metainfo = ctor->metainfo();
return std::empty(metainfo.info_hash_string()) ? nullptr : &metainfo;
}