mirror of
https://github.com/transmission/transmission.git
synced 2026-04-17 23:54:19 +01:00
refactor: move tr_pex/tr_variant converters to serializer.cc (#8655)
This commit is contained in:
@@ -1441,64 +1441,6 @@ std::vector<tr_pex> tr_pex::from_compact_ipv6(
|
||||
return pex;
|
||||
}
|
||||
|
||||
tr_variant::Map tr_pex::to_variant() const
|
||||
{
|
||||
auto pex = tr_variant::Map{ 2 };
|
||||
|
||||
auto buf = std::array<char, tr_socket_address::CompactSockAddrMaxBytes>{};
|
||||
auto* const buf_data = std::data(buf);
|
||||
auto* const begin = reinterpret_cast<std::byte*>(buf_data);
|
||||
auto* const end = to_compact(begin);
|
||||
|
||||
pex.try_emplace(TR_KEY_socket_address, std::string_view{ buf_data, static_cast<size_t>(end - begin) });
|
||||
pex.try_emplace(TR_KEY_flags, flags);
|
||||
|
||||
return pex;
|
||||
}
|
||||
|
||||
std::vector<tr_pex> tr_pex::from_variant(tr_variant const* const var, size_t const n_var)
|
||||
{
|
||||
auto pex_vec = std::vector<tr_pex>{};
|
||||
pex_vec.reserve(n_var);
|
||||
for (size_t i = 0; i < n_var; ++i)
|
||||
{
|
||||
auto* const map = var[i].get_if<tr_variant::Map>();
|
||||
if (map == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto sockaddr = map->value_if<std::string_view>(TR_KEY_socket_address);
|
||||
if (!sockaddr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pex = tr_pex{};
|
||||
auto* const compact = reinterpret_cast<std::byte const*>(std::data(*sockaddr));
|
||||
switch (std::size(*sockaddr))
|
||||
{
|
||||
case tr_socket_address::CompactSockAddrBytes[TR_AF_INET]:
|
||||
pex.socket_address = tr_socket_address::from_compact_ipv4(compact).first;
|
||||
break;
|
||||
|
||||
case tr_socket_address::CompactSockAddrBytes[TR_AF_INET6]:
|
||||
pex.socket_address = tr_socket_address::from_compact_ipv6(compact).first;
|
||||
break;
|
||||
|
||||
default:
|
||||
TR_ASSERT(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
pex.flags = static_cast<uint8_t>(map->value_if<int64_t>(TR_KEY_flags).value_or(0));
|
||||
|
||||
pex_vec.emplace_back(std::move(pex));
|
||||
}
|
||||
|
||||
return pex_vec;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
namespace
|
||||
|
||||
@@ -629,21 +629,6 @@ struct tr_pex
|
||||
uint8_t const* added_f,
|
||||
size_t added_f_len);
|
||||
|
||||
[[nodiscard]] tr_variant::Map to_variant() const;
|
||||
|
||||
[[nodiscard]] static tr_variant::Vector to_variant(tr_pex const* pex, size_t n_pex)
|
||||
{
|
||||
auto ret = tr_variant::Vector{};
|
||||
ret.reserve(n_pex);
|
||||
for (size_t i = 0; i < n_pex; ++i)
|
||||
{
|
||||
ret.emplace_back(pex[i].to_variant());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<tr_pex> from_variant(tr_variant const* var, size_t n_var);
|
||||
|
||||
[[nodiscard]] std::string display_name() const
|
||||
{
|
||||
return socket_address.display_name();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "libtransmission/quark.h"
|
||||
#include "libtransmission/resume.h"
|
||||
#include "libtransmission/session.h"
|
||||
#include "libtransmission/serializer.h"
|
||||
#include "libtransmission/string-utils.h"
|
||||
#include "libtransmission/torrent-ctor.h"
|
||||
#include "libtransmission/torrent-metainfo.h"
|
||||
@@ -49,19 +50,27 @@ void save_peers(tr_variant::Map& map, tr_torrent const* tor)
|
||||
{
|
||||
if (auto const pex = tr_peerMgrGetPeers(tor, TR_AF_INET, TR_PEERS_INTERESTING, MaxRememberedPeers); !std::empty(pex))
|
||||
{
|
||||
map.insert_or_assign(TR_KEY_peers2, tr_pex::to_variant(std::data(pex), std::size(pex)));
|
||||
map.insert_or_assign(TR_KEY_peers2, tr::serializer::to_variant(pex));
|
||||
}
|
||||
|
||||
if (auto const pex = tr_peerMgrGetPeers(tor, TR_AF_INET6, TR_PEERS_INTERESTING, MaxRememberedPeers); !std::empty(pex))
|
||||
{
|
||||
map.insert_or_assign(TR_KEY_peers2_6, tr_pex::to_variant(std::data(pex), std::size(pex)));
|
||||
map.insert_or_assign(TR_KEY_peers2_6, tr::serializer::to_variant(pex));
|
||||
}
|
||||
}
|
||||
|
||||
size_t add_peers(tr_torrent* tor, tr_variant::Vector const& l)
|
||||
{
|
||||
auto const n_pex = std::min(std::size(l), size_t{ MaxRememberedPeers });
|
||||
auto const pex = tr_pex::from_variant(std::data(l), n_pex);
|
||||
auto pex = std::vector<tr_pex>{};
|
||||
pex.reserve(n_pex);
|
||||
for (size_t i = 0; i < n_pex; ++i)
|
||||
{
|
||||
if (auto p = tr::serializer::to_value<tr_pex>(l[i]))
|
||||
{
|
||||
pex.emplace_back(std::move(*p));
|
||||
}
|
||||
}
|
||||
return tr_peerMgrAddPex(tor, TR_PEER_FROM_RESUME, std::data(pex), std::size(pex));
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "libtransmission/net.h" // for tr_port
|
||||
#include "libtransmission/open-files.h" // for tr_open_files::Preallocation
|
||||
#include "libtransmission/peer-io.h" // tr_preferred_transport
|
||||
#include "libtransmission/peer-mgr.h" // tr_pex
|
||||
#include "libtransmission/serializer.h"
|
||||
#include "libtransmission/string-utils.h"
|
||||
#include "libtransmission/utils.h" // for tr_strv_strip(), tr_strlower()
|
||||
@@ -505,6 +506,59 @@ tr_variant from_fs_path(std::filesystem::path const& path)
|
||||
{
|
||||
return from_u8string(path.u8string());
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
bool to_pex(tr_variant const& src, tr_pex* tgt)
|
||||
{
|
||||
auto* const map = src.get_if<tr_variant::Map>();
|
||||
if (map == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const sockaddr = map->value_if<std::string_view>(TR_KEY_socket_address);
|
||||
if (!sockaddr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pex = tr_pex{};
|
||||
auto* const compact = reinterpret_cast<std::byte const*>(std::data(*sockaddr));
|
||||
switch (std::size(*sockaddr))
|
||||
{
|
||||
case tr_socket_address::CompactSockAddrBytes[TR_AF_INET]:
|
||||
pex.socket_address = tr_socket_address::from_compact_ipv4(compact).first;
|
||||
break;
|
||||
|
||||
case tr_socket_address::CompactSockAddrBytes[TR_AF_INET6]:
|
||||
pex.socket_address = tr_socket_address::from_compact_ipv6(compact).first;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
pex.flags = static_cast<uint8_t>(map->value_if<int64_t>(TR_KEY_flags).value_or(0));
|
||||
|
||||
*tgt = std::move(pex);
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_variant from_pex(tr_pex const& val)
|
||||
{
|
||||
auto pex = tr_variant::Map{ 2U };
|
||||
|
||||
auto buf = std::array<char, tr_socket_address::CompactSockAddrMaxBytes>{};
|
||||
auto* const buf_data = std::data(buf);
|
||||
auto* const begin = reinterpret_cast<std::byte*>(buf_data);
|
||||
auto const* const end = val.to_compact(begin);
|
||||
|
||||
pex.try_emplace(TR_KEY_socket_address, std::string_view{ buf_data, static_cast<size_t>(end - begin) });
|
||||
pex.try_emplace(TR_KEY_flags, val.flags);
|
||||
|
||||
return pex;
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
void Converters::ensure_default_converters()
|
||||
@@ -523,6 +577,7 @@ void Converters::ensure_default_converters()
|
||||
Converters::add(to_log_level, from_log_level);
|
||||
Converters::add(to_mode_t, from_mode_t);
|
||||
Converters::add(to_msec, from_msec);
|
||||
Converters::add(to_pex, from_pex);
|
||||
Converters::add(to_port, from_port);
|
||||
Converters::add(to_preallocation_mode, from_preallocation_mode);
|
||||
Converters::add(to_preferred_transport, from_preferred_transport);
|
||||
|
||||
@@ -178,6 +178,31 @@ TEST_F(SerializerTest, usesFsPath)
|
||||
EXPECT_EQ(toString(actual.u8string()), toString(expected.u8string()));
|
||||
}
|
||||
|
||||
TEST_F(SerializerTest, usesTrPex)
|
||||
{
|
||||
static auto constexpr CompactIp = std::array{ '\x7F', '\0', '\0', '\1', '\x73', '\x1A' }; // 127.0.0.1:6771
|
||||
static_assert(CompactIp.size() == tr_socket_address::CompactSockAddrBytes[TR_AF_INET]);
|
||||
|
||||
auto const expected_flags = static_cast<uint8_t>(tr_rand_int(0x100U));
|
||||
auto const expected_sockaddr = tr_socket_address::from_compact_ipv4(reinterpret_cast<std::byte const*>(CompactIp.data()))
|
||||
.first;
|
||||
auto const var = Converters::serialize(tr_pex{ expected_sockaddr, expected_flags });
|
||||
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const compact_ip = map->value_if<std::string_view>(TR_KEY_socket_address);
|
||||
ASSERT_TRUE(compact_ip);
|
||||
EXPECT_EQ(
|
||||
std::lexicographical_compare_three_way(compact_ip->begin(), compact_ip->end(), CompactIp.begin(), CompactIp.end()),
|
||||
std::strong_ordering::equivalent);
|
||||
EXPECT_EQ(map->value_if<int64_t>(TR_KEY_flags), expected_flags);
|
||||
|
||||
auto actual = tr_pex{};
|
||||
EXPECT_TRUE(Converters::deserialize(var, &actual));
|
||||
EXPECT_EQ(actual.socket_address, expected_sockaddr);
|
||||
EXPECT_EQ(actual.flags, expected_flags);
|
||||
}
|
||||
|
||||
TEST_F(SerializerTest, u8StringWarnsOnInvalidUtf8)
|
||||
{
|
||||
auto const bad = std::string{ static_cast<char>(0xC3), static_cast<char>(0x28) };
|
||||
|
||||
Reference in New Issue
Block a user