fix: restore loose data type parsing in RPC and `settings.json` (#6723)

* refactor: incorporate lenient parsing from `tr_variantGet*()` functions into `tr_variant`

* fix: restore loose data types in RPC and settings.json

* fix: workaround GCC defect

* fix: MSVC build
This commit is contained in:
Yat Ho 2024-04-01 03:06:36 +08:00 committed by GitHub
parent 460ce7c302
commit e1c9fbde60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 238 additions and 203 deletions

View File

@ -105,12 +105,12 @@ void tr_idle_function_done(struct tr_rpc_idle_data* data, std::string_view resul
{
tr_torrent* tor = nullptr;
if (auto const* val = var.get_if<int64_t>(); val != nullptr)
if (auto const val = var.value_if<int64_t>())
{
tor = torrents.get(*val);
}
if (auto const* val = var.get_if<std::string_view>(); val != nullptr)
if (auto const val = var.value_if<std::string_view>())
{
if (*val == "recently-active"sv)
{
@ -741,7 +741,7 @@ char const* torrentGet(tr_session* session, tr_variant::Map const& args_in, tr_v
keys.reserve(n_fields);
for (auto const& field : *fields_vec)
{
if (auto const* field_sv = field.get_if<std::string_view>(); field_sv != nullptr)
if (auto const field_sv = field.value_if<std::string_view>())
{
if (auto const key = tr_quark_lookup(*field_sv); key && isSupportedTorrentGetField(*key))
{
@ -788,7 +788,7 @@ char const* torrentGet(tr_session* session, tr_variant::Map const& args_in, tr_v
labels.reserve(n_labels);
for (auto const& label_var : labels_vec)
{
if (auto const* value = label_var.get_if<std::string_view>(); value != nullptr)
if (auto const value = label_var.value_if<std::string_view>())
{
auto const label = tr_strv_strip(*value);
@ -840,7 +840,7 @@ char const* set_labels(tr_torrent* tor, tr_variant::Vector const& list)
{
for (auto const& file_var : files_vec)
{
if (auto const* val = file_var.get_if<int64_t>(); val != nullptr)
if (auto const val = file_var.value_if<int64_t>())
{
if (auto const idx = static_cast<tr_file_index_t>(*val); idx < n_files)
{
@ -887,7 +887,7 @@ char const* add_tracker_urls(tr_torrent* tor, tr_variant::Vector const& urls_vec
for (auto const& url_var : urls_vec)
{
if (auto const* val = url_var.get_if<std::string_view>(); val != nullptr)
if (auto const val = url_var.value_if<std::string_view>())
{
ann.add(*val);
}
@ -909,10 +909,10 @@ char const* replace_trackers(tr_torrent* tor, tr_variant::Vector const& urls_vec
for (size_t i = 0, vec_size = std::size(urls_vec); i + 1 < vec_size; i += 2U)
{
auto const* id = urls_vec[i].get_if<int64_t>();
auto const* url = urls_vec[i + 1U].get_if<std::string_view>();
auto const id = urls_vec[i].value_if<int64_t>();
auto const url = urls_vec[i + 1U].value_if<std::string_view>();
if (id != nullptr && url != nullptr)
if (id && url)
{
ann.replace(static_cast<tr_tracker_id_t>(*id), *url);
}
@ -934,7 +934,7 @@ char const* remove_trackers(tr_torrent* tor, tr_variant::Vector const& ids_vec)
for (auto const& id_var : ids_vec)
{
if (auto const* val = id_var.get_if<int64_t>(); val != nullptr)
if (auto const val = id_var.value_if<int64_t>())
{
ann.remove(static_cast<tr_tracker_id_t>(*val));
}
@ -955,7 +955,7 @@ char const* torrentSet(tr_session* session, tr_variant::Map const& args_in, tr_v
for (auto* tor : getTorrents(session, args_in))
{
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_bandwidthPriority); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_bandwidthPriority))
{
if (auto const priority = static_cast<tr_priority_t>(*val); tr_isPriority(priority))
{
@ -963,7 +963,7 @@ char const* torrentSet(tr_session* session, tr_variant::Map const& args_in, tr_v
}
}
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_group); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_group))
{
tor->set_bandwidth_group(*val);
}
@ -983,7 +983,7 @@ char const* torrentSet(tr_session* session, tr_variant::Map const& args_in, tr_v
errmsg = set_file_dls(tor, true, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_peer_limit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_peer_limit))
{
tr_torrentSetPeerLimit(tor, *val);
}
@ -1003,77 +1003,77 @@ char const* torrentSet(tr_session* session, tr_variant::Map const& args_in, tr_v
errmsg = set_file_priorities(tor, TR_PRI_NORMAL, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_downloadLimit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_downloadLimit))
{
tr_torrentSetSpeedLimit_KBps(tor, TR_DOWN, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_sequentialDownload); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_sequentialDownload))
{
tor->set_sequential_download(*val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_downloadLimited); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_downloadLimited))
{
tor->use_speed_limit(TR_DOWN, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_honorsSessionLimits); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_honorsSessionLimits))
{
tr_torrentUseSessionLimits(tor, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_uploadLimit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_uploadLimit))
{
tr_torrentSetSpeedLimit_KBps(tor, TR_UP, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_uploadLimited); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_uploadLimited))
{
tor->use_speed_limit(TR_UP, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_seedIdleLimit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_seedIdleLimit))
{
tor->set_idle_limit_minutes(static_cast<uint16_t>(*val));
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_seedIdleMode); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_seedIdleMode))
{
tor->set_idle_limit_mode(static_cast<tr_idlelimit>(*val));
}
if (auto const* val = args_in.find_if<double>(TR_KEY_seedRatioLimit); val != nullptr)
if (auto const val = args_in.value_if<double>(TR_KEY_seedRatioLimit))
{
tor->set_seed_ratio(*val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_seedRatioMode); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_seedRatioMode))
{
tor->set_seed_ratio_mode(static_cast<tr_ratiolimit>(*val));
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_queuePosition); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_queuePosition))
{
tr_torrentSetQueuePosition(tor, static_cast<size_t>(*val));
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerAdd); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerAdd))
{
errmsg = add_tracker_urls(tor, *val);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerRemove); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerRemove))
{
errmsg = remove_trackers(tor, *val);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerReplace); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_trackerReplace))
{
errmsg = replace_trackers(tor, *val);
}
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_trackerList); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_trackerList))
{
if (!tor->set_announce_list(*val))
{
@ -1089,8 +1089,8 @@ char const* torrentSet(tr_session* session, tr_variant::Map const& args_in, tr_v
char const* torrentSetLocation(tr_session* session, tr_variant::Map const& args_in, tr_variant::Map& /*args_out*/)
{
auto const* const location = args_in.find_if<std::string_view>(TR_KEY_location);
if (location == nullptr)
auto const location = args_in.value_if<std::string_view>(TR_KEY_location);
if (!location)
{
return "no location";
}
@ -1174,7 +1174,7 @@ char const* portTest(tr_session* session, tr_variant::Map const& args_in, struct
auto options = tr_web::FetchOptions{ url, onPortTested, idle_data };
options.timeout_secs = TimeoutSecs;
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_ipProtocol); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_ipProtocol))
{
if (*val == "ipv4"sv)
{
@ -1359,7 +1359,7 @@ bool isCurlURL(std::string_view url)
files.reserve(n_files);
for (auto const& idx_var : idx_vec)
{
if (auto const* val = idx_var.get_if<int64_t>(); val != nullptr)
if (auto const val = idx_var.value_if<int64_t>())
{
files.emplace_back(static_cast<tr_file_index_t>(*val));
}
@ -1395,52 +1395,52 @@ char const* torrentAdd(tr_session* session, tr_variant::Map const& args_in, tr_r
ctor.set_download_dir(TR_FORCE, *download_dir);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_paused); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_paused))
{
ctor.set_paused(TR_FORCE, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_peer_limit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_peer_limit))
{
ctor.set_peer_limit(TR_FORCE, static_cast<uint16_t>(*val));
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_bandwidthPriority); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_bandwidthPriority))
{
ctor.set_bandwidth_priority(static_cast<tr_priority_t>(*val));
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_files_unwanted); val != nullptr)
if (auto const val = args_in.find_if<tr_variant::Vector>(TR_KEY_files_unwanted))
{
auto const files = file_list_from_list(*val);
ctor.set_files_wanted(std::data(files), std::size(files), false);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_files_wanted); val != nullptr)
if (auto const val = args_in.find_if<tr_variant::Vector>(TR_KEY_files_wanted))
{
auto const files = file_list_from_list(*val);
ctor.set_files_wanted(std::data(files), std::size(files), true);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_low); val != nullptr)
if (auto const val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_low))
{
auto const files = file_list_from_list(*val);
ctor.set_file_priorities(std::data(files), std::size(files), TR_PRI_LOW);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_normal); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_normal))
{
auto const files = file_list_from_list(*val);
ctor.set_file_priorities(std::data(files), std::size(files), TR_PRI_NORMAL);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_high); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_priority_high))
{
auto const files = file_list_from_list(*val);
ctor.set_file_priorities(std::data(files), std::size(files), TR_PRI_HIGH);
}
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_labels); val != nullptr)
if (auto const* val = args_in.find_if<tr_variant::Vector>(TR_KEY_labels))
{
auto [labels, errmsg] = make_labels(*val);
@ -1493,7 +1493,7 @@ char const* torrentAdd(tr_session* session, tr_variant::Map const& args_in, tr_r
void add_strings_from_var(std::set<std::string_view>& strings, tr_variant const& var)
{
if (auto const* val = var.get_if<std::string_view>(); val != nullptr)
if (auto const val = var.value_if<std::string_view>())
{
strings.insert(*val);
return;
@ -1548,29 +1548,29 @@ char const* groupSet(tr_session* session, tr_variant::Map const& args_in, tr_var
auto& group = session->getBandwidthGroup(name);
auto limits = group.get_limits();
if (auto const* const val = args_in.find_if<bool>(TR_KEY_speed_limit_down_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_speed_limit_down_enabled))
{
limits.down_limited = *val;
}
if (auto const* const val = args_in.find_if<bool>(TR_KEY_speed_limit_up_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_speed_limit_up_enabled))
{
limits.up_limited = *val;
}
if (auto const* const val = args_in.find_if<int64_t>(TR_KEY_speed_limit_down); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_speed_limit_down))
{
limits.down_limit = Speed{ *val, Speed::Units::KByps };
}
if (auto const* const val = args_in.find_if<int64_t>(TR_KEY_speed_limit_up); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_speed_limit_up))
{
limits.up_limit = Speed{ *val, Speed::Units::KByps };
}
group.set_limits(limits);
if (auto const* const val = args_in.find_if<bool>(TR_KEY_honorsSessionLimits); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_honorsSessionLimits))
{
group.honor_parent_limits(TR_UP, *val);
group.honor_parent_limits(TR_DOWN, *val);
@ -1595,52 +1595,52 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v
return "incomplete torrents directory path is not absolute";
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_cache_size_mb); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_cache_size_mb))
{
tr_sessionSetCacheLimit_MB(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_alt_speed_up); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_alt_speed_up))
{
tr_sessionSetAltSpeed_KBps(session, TR_UP, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_alt_speed_down); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_alt_speed_down))
{
tr_sessionSetAltSpeed_KBps(session, TR_DOWN, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_alt_speed_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_alt_speed_enabled))
{
tr_sessionUseAltSpeed(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_alt_speed_time_begin); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_alt_speed_time_begin))
{
tr_sessionSetAltSpeedBegin(session, static_cast<size_t>(*val));
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_alt_speed_time_end); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_alt_speed_time_end))
{
tr_sessionSetAltSpeedEnd(session, static_cast<size_t>(*val));
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_alt_speed_time_day); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_alt_speed_time_day))
{
tr_sessionSetAltSpeedDay(session, static_cast<tr_sched_day>(*val));
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_alt_speed_time_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_alt_speed_time_enabled))
{
tr_sessionUseAltSpeedTime(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_blocklist_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_blocklist_enabled))
{
session->set_blocklist_enabled(*val);
}
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_blocklist_url); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_blocklist_url))
{
session->setBlocklistUrl(*val);
}
@ -1650,27 +1650,27 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v
session->setDownloadDir(*download_dir);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_queue_stalled_minutes); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_queue_stalled_minutes))
{
tr_sessionSetQueueStalledMinutes(session, static_cast<int>(*val));
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_queue_stalled_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_queue_stalled_enabled))
{
tr_sessionSetQueueStalledEnabled(session, *val);
}
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_default_trackers); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_default_trackers))
{
session->setDefaultTrackers(*val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_download_queue_size); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_download_queue_size))
{
tr_sessionSetQueueSize(session, TR_DOWN, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_download_queue_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_download_queue_enabled))
{
tr_sessionSetQueueEnabled(session, TR_DOWN, *val);
}
@ -1680,135 +1680,135 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v
session->setIncompleteDir(*incomplete_dir);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_incomplete_dir_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_incomplete_dir_enabled))
{
session->useIncompleteDir(*val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_peer_limit_global); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_peer_limit_global))
{
tr_sessionSetPeerLimit(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_peer_limit_per_torrent); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_peer_limit_per_torrent))
{
tr_sessionSetPeerLimitPerTorrent(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_pex_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_pex_enabled))
{
tr_sessionSetPexEnabled(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_dht_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_dht_enabled))
{
tr_sessionSetDHTEnabled(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_utp_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_utp_enabled))
{
tr_sessionSetUTPEnabled(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_lpd_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_lpd_enabled))
{
tr_sessionSetLPDEnabled(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_peer_port_random_on_start); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_peer_port_random_on_start))
{
tr_sessionSetPeerPortRandomOnStart(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_peer_port); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_peer_port))
{
tr_sessionSetPeerPort(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_port_forwarding_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_port_forwarding_enabled))
{
tr_sessionSetPortForwardingEnabled(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_rename_partial_files); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_rename_partial_files))
{
tr_sessionSetIncompleteFileNamingEnabled(session, *val);
}
if (auto const* val = args_in.find_if<double>(TR_KEY_seedRatioLimit); val != nullptr)
if (auto const val = args_in.value_if<double>(TR_KEY_seedRatioLimit))
{
tr_sessionSetRatioLimit(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_seedRatioLimited); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_seedRatioLimited))
{
tr_sessionSetRatioLimited(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_idle_seeding_limit); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_idle_seeding_limit))
{
tr_sessionSetIdleLimit(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_idle_seeding_limit_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_idle_seeding_limit_enabled))
{
tr_sessionSetIdleLimited(session, *val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_start_added_torrents); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_start_added_torrents))
{
tr_sessionSetPaused(session, !*val);
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_seed_queue_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_seed_queue_enabled))
{
tr_sessionSetQueueEnabled(session, TR_UP, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_seed_queue_size); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_seed_queue_size))
{
tr_sessionSetQueueSize(session, TR_UP, *val);
}
for (auto const& [enabled_key, script_key, script] : tr_session::Scripts)
{
if (auto const* val = args_in.find_if<bool>(enabled_key); val != nullptr)
if (auto const val = args_in.value_if<bool>(enabled_key))
{
session->useScript(script, *val);
}
if (auto const* val = args_in.find_if<std::string_view>(script_key); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(script_key))
{
session->setScript(script, *val);
}
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_trash_original_torrent_files); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_trash_original_torrent_files))
{
tr_sessionSetDeleteSource(session, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_speed_limit_down); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_speed_limit_down))
{
session->set_speed_limit(TR_DOWN, Speed{ *val, Speed::Units::KByps });
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_speed_limit_down_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_speed_limit_down_enabled))
{
tr_sessionLimitSpeed(session, TR_DOWN, *val);
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_speed_limit_up); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_speed_limit_up))
{
session->set_speed_limit(TR_UP, Speed{ *val, Speed::Units::KByps });
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_speed_limit_up_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_speed_limit_up_enabled))
{
tr_sessionLimitSpeed(session, TR_UP, *val);
}
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_encryption); val != nullptr)
if (auto const val = args_in.value_if<std::string_view>(TR_KEY_encryption))
{
if (*val == "required"sv)
{
@ -1824,12 +1824,12 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v
}
}
if (auto const* val = args_in.find_if<int64_t>(TR_KEY_anti_brute_force_threshold); val != nullptr)
if (auto const val = args_in.value_if<int64_t>(TR_KEY_anti_brute_force_threshold))
{
tr_sessionSetAntiBruteForceThreshold(session, static_cast<int>(*val));
}
if (auto const* val = args_in.find_if<bool>(TR_KEY_anti_brute_force_enabled); val != nullptr)
if (auto const val = args_in.value_if<bool>(TR_KEY_anti_brute_force_enabled))
{
tr_sessionSetAntiBruteForceEnabled(session, *val);
}
@ -1994,7 +1994,7 @@ namespace session_get_helpers
{
for (auto const& field_var : *fields_vec)
{
if (auto const* field_name = field_var.get_if<std::string_view>(); field_name != nullptr)
if (auto const field_name = field_var.value_if<std::string_view>())
{
if (auto const field_id = tr_quark_lookup(*field_name); field_id)
{
@ -2126,13 +2126,13 @@ void tr_rpc_request_exec(tr_session* session, tr_variant const& request, tr_rpc_
if (request_map != nullptr)
{
// find the args
if (auto const* val = request_map->find_if<tr_variant::Map>(TR_KEY_arguments); val != nullptr)
if (auto const* val = request_map->find_if<tr_variant::Map>(TR_KEY_arguments))
{
args_in = val;
}
// find the requested method
if (auto const* val = request_map->find_if<std::string_view>(TR_KEY_method); val != nullptr)
if (auto const val = request_map->value_if<std::string_view>(TR_KEY_method))
{
method_name = *val;
}

View File

@ -101,29 +101,29 @@ void bandwidthGroupRead(tr_session* session, std::string_view config_dir)
auto& group = session->getBandwidthGroup(tr_interned_string{ key });
auto limits = tr_bandwidth_limits{};
if (auto const* val = group_map->find_if<bool>(TR_KEY_uploadLimited); val != nullptr)
if (auto const val = group_map->value_if<bool>(TR_KEY_uploadLimited))
{
limits.up_limited = *val;
}
if (auto const* val = group_map->find_if<bool>(TR_KEY_downloadLimited); val != nullptr)
if (auto const val = group_map->value_if<bool>(TR_KEY_downloadLimited))
{
limits.down_limited = *val;
}
if (auto const* val = group_map->find_if<int64_t>(TR_KEY_uploadLimit); val != nullptr)
if (auto const val = group_map->value_if<int64_t>(TR_KEY_uploadLimit))
{
limits.up_limit = Speed{ *val, Speed::Units::KByps };
}
if (auto const* val = group_map->find_if<int64_t>(TR_KEY_downloadLimit); val != nullptr)
if (auto const val = group_map->value_if<int64_t>(TR_KEY_downloadLimit))
{
limits.down_limit = Speed{ *val, Speed::Units::KByps };
}
group.set_limits(limits);
if (auto const* val = group_map->find_if<bool>(TR_KEY_honorsSessionLimits); val != nullptr)
if (auto const val = group_map->value_if<bool>(TR_KEY_honorsSessionLimits))
{
group.honor_parent_limits(TR_UP, *val);
group.honor_parent_limits(TR_DOWN, *val);
@ -565,7 +565,7 @@ tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled
// if logging is desired, start it now before doing more work
if (auto const* settings_map = settings.get_if<tr_variant::Map>(); settings_map != nullptr)
{
if (auto const* val = settings_map->find_if<bool>(TR_KEY_message_level); val != nullptr)
if (auto const val = settings_map->value_if<bool>(TR_KEY_message_level))
{
tr_logSetLevel(static_cast<tr_log_level>(*val));
}

View File

@ -38,7 +38,7 @@ using Lookup = std::array<std::pair<std::string_view, T>, N>;
bool load_bool(tr_variant const& src, bool* tgt)
{
if (auto val = src.get_if<bool>(); val != nullptr)
if (auto val = src.value_if<bool>())
{
*tgt = *val;
return true;
@ -56,7 +56,7 @@ tr_variant save_bool(bool const& val)
bool load_double(tr_variant const& src, double* tgt)
{
if (auto val = src.get_if<double>(); val != nullptr)
if (auto val = src.value_if<double>())
{
*tgt = *val;
return true;
@ -82,7 +82,7 @@ bool load_encryption_mode(tr_variant const& src, tr_encryption_mode* tgt)
{
static constexpr auto& Keys = EncryptionKeys;
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
auto const needle = tr_strlower(tr_strv_strip(*val));
@ -96,7 +96,7 @@ bool load_encryption_mode(tr_variant const& src, tr_encryption_mode* tgt)
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
for (auto const& [key, encryption] : Keys)
{
@ -132,7 +132,7 @@ bool load_log_level(tr_variant const& src, tr_log_level* tgt)
{
static constexpr auto& Keys = LogKeys;
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
auto const needle = tr_strlower(tr_strv_strip(*val));
@ -146,7 +146,7 @@ bool load_log_level(tr_variant const& src, tr_log_level* tgt)
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
for (auto const& [name, log_level] : Keys)
{
@ -170,7 +170,7 @@ tr_variant save_log_level(tr_log_level const& val)
bool load_mode_t(tr_variant const& src, tr_mode_t* tgt)
{
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
if (auto const mode = tr_num_parse<uint32_t>(*val, nullptr, 8); mode)
{
@ -179,7 +179,7 @@ bool load_mode_t(tr_variant const& src, tr_mode_t* tgt)
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
*tgt = static_cast<tr_mode_t>(*val);
return true;
@ -197,7 +197,7 @@ tr_variant save_mode_t(tr_mode_t const& val)
bool load_msec(tr_variant const& src, std::chrono::milliseconds* tgt)
{
if (auto val = src.get_if<int64_t>(); val != nullptr)
if (auto val = src.value_if<int64_t>())
{
*tgt = std::chrono::milliseconds(*val);
return true;
@ -215,7 +215,7 @@ tr_variant save_msec(std::chrono::milliseconds const& src)
bool load_port(tr_variant const& src, tr_port* tgt)
{
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
*tgt = tr_port::from_host(*val);
return true;
@ -243,7 +243,7 @@ bool load_preallocation_mode(tr_variant const& src, tr_open_files::Preallocation
{
static constexpr auto& Keys = PreallocationKeys;
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
auto const needle = tr_strlower(tr_strv_strip(*val));
@ -257,7 +257,7 @@ bool load_preallocation_mode(tr_variant const& src, tr_open_files::Preallocation
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
for (auto const& [name, value] : Keys)
{
@ -288,7 +288,7 @@ bool load_preferred_transport(tr_variant const& src, tr_preferred_transport* tgt
{
static constexpr auto& Keys = PreferredTransportKeys;
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
auto const needle = tr_strlower(tr_strv_strip(*val));
@ -302,7 +302,7 @@ bool load_preferred_transport(tr_variant const& src, tr_preferred_transport* tgt
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
for (auto const& [name, value] : Keys)
{
@ -334,7 +334,7 @@ tr_variant save_preferred_transport(tr_preferred_transport const& val)
bool load_size_t(tr_variant const& src, size_t* tgt)
{
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
*tgt = static_cast<size_t>(*val);
return true;
@ -352,7 +352,7 @@ tr_variant save_size_t(size_t const& val)
bool load_string(tr_variant const& src, std::string* tgt)
{
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
*tgt = std::string{ *val };
return true;
@ -370,7 +370,7 @@ tr_variant save_string(std::string const& val)
bool load_tos_t(tr_variant const& src, tr_tos_t* tgt)
{
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
if (auto const tos = tr_tos_t::from_string(*val); tos)
{
@ -381,7 +381,7 @@ bool load_tos_t(tr_variant const& src, tr_tos_t* tgt)
return false;
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
*tgt = tr_tos_t{ static_cast<int>(*val) };
return true;
@ -406,7 +406,7 @@ bool load_verify_added_mode(tr_variant const& src, tr_verify_added_mode* tgt)
{
static constexpr auto& Keys = VerifyModeKeys;
if (auto const* val = src.get_if<std::string_view>(); val != nullptr)
if (auto const val = src.value_if<std::string_view>())
{
auto const needle = tr_strlower(tr_strv_strip(*val));
@ -420,7 +420,7 @@ bool load_verify_added_mode(tr_variant const& src, tr_verify_added_mode* tgt)
}
}
if (auto const* val = src.get_if<int64_t>(); val != nullptr)
if (auto const val = src.value_if<int64_t>())
{
for (auto const& [name, value] : Keys)
{

View File

@ -50,6 +50,21 @@ namespace
return tr_variant::NoneIndex;
}
template<typename T>
[[nodiscard]] bool value_if(tr_variant const* const var, T* const setme)
{
if (var != nullptr)
{
if (auto val = var->value_if<T>())
{
*setme = *val;
return true;
}
}
return false;
}
template<typename T>
[[nodiscard]] tr_variant* dict_set(tr_variant* const var, tr_quark const key, T&& val)
{
@ -82,6 +97,79 @@ template<typename T>
// ---
// Specialisations for int64_t and bool could have been inline and constexpr,
// but aren't because https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282
template<>
[[nodiscard]] std::optional<int64_t> tr_variant::value_if() noexcept
{
switch (index())
{
case IntIndex:
return *get_if<IntIndex>();
case BoolIndex:
return *get_if<BoolIndex>() ? 1 : 0;
default:
return {};
}
}
template<>
[[nodiscard]] std::optional<bool> tr_variant::value_if() noexcept
{
switch (index())
{
case BoolIndex:
return *get_if<BoolIndex>();
case IntIndex:
if (auto const val = *get_if<IntIndex>(); val == 0 || val == 1)
{
return val != 0;
}
break;
case StringIndex:
if (auto const val = *get_if<StringIndex>(); val == "true")
{
return true;
}
else if (val == "false")
{
return false;
}
break;
default:
break;
}
return {};
}
template<>
[[nodiscard]] std::optional<double> tr_variant::value_if() noexcept
{
switch (index())
{
case DoubleIndex:
return *get_if<DoubleIndex>();
case IntIndex:
return static_cast<double>(*get_if<IntIndex>());
case StringIndex:
return tr_num_parse<double>(*get_if<StringIndex>());
default:
return {};
}
}
// ---
tr_variant::StringHolder::StringHolder(std::string&& str) noexcept
: str_{ std::move(str) }
{
@ -206,38 +294,12 @@ bool tr_variantListRemove(tr_variant* const var, size_t pos)
bool tr_variantGetInt(tr_variant const* const var, int64_t* setme)
{
switch (variant_index(var))
{
case tr_variant::IntIndex:
if (setme != nullptr)
{
*setme = *var->get_if<tr_variant::IntIndex>();
}
return true;
case tr_variant::BoolIndex:
if (setme != nullptr)
{
*setme = *var->get_if<tr_variant::BoolIndex>() ? 1 : 0;
}
return true;
default:
return false;
}
return value_if(var, setme);
}
bool tr_variantGetStrView(tr_variant const* const var, std::string_view* setme)
{
switch (variant_index(var))
{
case tr_variant::StringIndex:
*setme = *var->get_if<tr_variant::StringIndex>();
return true;
default:
return false;
}
return value_if(var, setme);
}
bool tr_variantGetRaw(tr_variant const* v, std::byte const** setme_raw, size_t* setme_len)
@ -266,63 +328,12 @@ bool tr_variantGetRaw(tr_variant const* v, uint8_t const** setme_raw, size_t* se
bool tr_variantGetBool(tr_variant const* const var, bool* setme)
{
switch (variant_index(var))
{
case tr_variant::BoolIndex:
*setme = *var->get_if<tr_variant::BoolIndex>();
return true;
case tr_variant::IntIndex:
if (auto const val = *var->get_if<tr_variant::IntIndex>(); val == 0 || val == 1)
{
*setme = val != 0;
return true;
}
break;
case tr_variant::StringIndex:
if (auto const val = *var->get_if<tr_variant::StringIndex>(); val == "true"sv)
{
*setme = true;
return true;
}
else if (val == "false"sv)
{
*setme = false;
return true;
}
break;
default:
break;
}
return false;
return value_if(var, setme);
}
bool tr_variantGetReal(tr_variant const* const var, double* setme)
{
switch (variant_index(var))
{
case tr_variant::DoubleIndex:
*setme = *var->get_if<tr_variant::DoubleIndex>();
return true;
case tr_variant::IntIndex:
*setme = static_cast<double>(*var->get_if<tr_variant::IntIndex>());
return true;
case tr_variant::StringIndex:
if (auto const val = tr_num_parse<double>(*var->get_if<tr_variant::StringIndex>()); val)
{
*setme = *val;
return true;
}
[[fallthrough]];
default:
return false;
}
return value_if(var, setme);
}
bool tr_variantDictFindInt(tr_variant* const var, tr_quark key, int64_t* setme)

View File

@ -158,11 +158,11 @@ public:
}
template<typename Type>
[[nodiscard]] TR_CONSTEXPR20 std::optional<Type> value_if(tr_quark const key) const noexcept
[[nodiscard]] std::optional<Type> value_if(tr_quark const key) const noexcept
{
if (auto const* const value = find_if<Type>(key); value != nullptr)
if (auto it = find(key); it != end())
{
return std::optional<Type>{ *value };
return it->second.value_if<Type>();
}
return {};
@ -310,6 +310,23 @@ public:
return const_cast<tr_variant*>(this)->get_if<Index>();
}
template<typename Val>
[[nodiscard]] constexpr std::optional<Val> value_if() noexcept
{
if (auto const* const val = get_if<Val>())
{
return *val;
}
return {};
}
template<typename Val>
[[nodiscard]] std::optional<Val> value_if() const noexcept
{
return const_cast<tr_variant*>(this)->value_if<Val>();
}
template<typename Val>
[[nodiscard]] constexpr bool holds_alternative() const noexcept
{
@ -371,6 +388,13 @@ private:
std::variant<std::monostate, bool, int64_t, double, StringHolder, Vector, Map> val_;
};
template<>
[[nodiscard]] std::optional<int64_t> tr_variant::value_if() noexcept;
template<>
[[nodiscard]] std::optional<bool> tr_variant::value_if() noexcept;
template<>
[[nodiscard]] std::optional<double> tr_variant::value_if() noexcept;
// --- Strings
bool tr_variantGetStrView(tr_variant const* variant, std::string_view* setme);