2014-07-06 21:18:00 +02:00
|
|
|
/*
|
|
|
|
|
2018-04-09 09:04:33 +02:00
|
|
|
Copyright (c) 2012-2018, Arvid Norberg
|
2014-07-06 21:18:00 +02:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "libtorrent/config.hpp"
|
|
|
|
#include "libtorrent/assert.hpp"
|
|
|
|
#include "libtorrent/settings_pack.hpp"
|
|
|
|
#include "libtorrent/aux_/session_impl.hpp"
|
2017-02-05 04:05:53 +01:00
|
|
|
#include "libtorrent/aux_/array.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2015-01-03 17:52:22 +01:00
|
|
|
template <class T>
|
2016-06-18 20:01:38 +02:00
|
|
|
bool compare_first(std::pair<std::uint16_t, T> const& lhs
|
|
|
|
, std::pair<std::uint16_t, T> const& rhs)
|
2015-01-03 17:52:22 +01:00
|
|
|
{
|
|
|
|
return lhs.first < rhs.first;
|
|
|
|
}
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
template <class T>
|
2016-08-13 13:04:53 +02:00
|
|
|
void insort_replace(std::vector<std::pair<std::uint16_t, T>>& c, std::pair<std::uint16_t, T> v)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(c.begin(), c.end(), v, &compare_first<T>);
|
|
|
|
if (i != c.end() && i->first == v.first) i->second = std::move(v.second);
|
|
|
|
else c.emplace(i, std::move(v));
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
2017-02-05 09:13:26 +01:00
|
|
|
|
|
|
|
// return the string, unless it's null, in which case the empty string is
|
|
|
|
// returned
|
|
|
|
char const* ensure_string(char const* str)
|
2017-02-05 18:51:48 +01:00
|
|
|
{ return str == nullptr ? "" : str; }
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace libtorrent {
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
struct str_setting_entry_t
|
|
|
|
{
|
|
|
|
// the name of this setting. used for serialization and deserialization
|
|
|
|
char const* name;
|
|
|
|
// if present, this function is called when the setting is changed
|
|
|
|
void (aux::session_impl::*fun)();
|
|
|
|
char const *default_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct int_setting_entry_t
|
|
|
|
{
|
|
|
|
// the name of this setting. used for serialization and deserialization
|
|
|
|
char const* name;
|
|
|
|
// if present, this function is called when the setting is changed
|
|
|
|
void (aux::session_impl::*fun)();
|
|
|
|
int default_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bool_setting_entry_t
|
|
|
|
{
|
|
|
|
// the name of this setting. used for serialization and deserialization
|
|
|
|
char const* name;
|
|
|
|
// if present, this function is called when the setting is changed
|
|
|
|
void (aux::session_impl::*fun)();
|
|
|
|
bool default_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define SET(name, default_value, fun) { #name, fun, default_value }
|
2014-07-22 07:35:05 +02:00
|
|
|
|
2016-09-21 08:49:23 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
#define DEPRECATED_SET(name, default_value, fun) { #name, fun, default_value }
|
|
|
|
#else
|
|
|
|
#define DEPRECATED_SET(name, default_value, fun) { "", nullptr, 0 }
|
2017-03-01 00:06:02 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef TORRENT_WINDOWS
|
2017-04-09 00:24:50 +02:00
|
|
|
constexpr int CLOSE_FILE_INTERVAL = 120;
|
2017-03-01 00:06:02 +01:00
|
|
|
#else
|
2017-04-09 00:24:50 +02:00
|
|
|
constexpr int CLOSE_FILE_INTERVAL = 0;
|
2014-07-06 21:18:00 +02:00
|
|
|
#endif
|
|
|
|
|
2015-04-19 08:28:21 +02:00
|
|
|
namespace {
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
using aux::session_impl;
|
|
|
|
|
2017-02-05 04:05:53 +01:00
|
|
|
aux::array<str_setting_entry_t, settings_pack::num_string_settings> const str_settings
|
|
|
|
({{
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(user_agent, "libtorrent/" LIBTORRENT_VERSION, &session_impl::update_user_agent),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(announce_ip, nullptr, nullptr),
|
|
|
|
SET(mmap_cache, nullptr, nullptr),
|
|
|
|
SET(handshake_client_version, nullptr, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(outgoing_interfaces, "", &session_impl::update_outgoing_interfaces),
|
2016-02-23 02:14:53 +01:00
|
|
|
#if !TORRENT_USE_IPV6
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(listen_interfaces, "0.0.0.0:6881", &session_impl::update_listen_interfaces),
|
2016-02-23 02:14:53 +01:00
|
|
|
#else
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(listen_interfaces, "0.0.0.0:6881,[::]:6881", &session_impl::update_listen_interfaces),
|
2016-02-23 02:14:53 +01:00
|
|
|
#endif
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(proxy_hostname, "", &session_impl::update_proxy),
|
|
|
|
SET(proxy_username, "", &session_impl::update_proxy),
|
|
|
|
SET(proxy_password, "", &session_impl::update_proxy),
|
|
|
|
SET(i2p_hostname, "", &session_impl::update_i2p_bridge),
|
2018-01-23 23:06:12 +01:00
|
|
|
SET(peer_fingerprint, "-LT1200-", nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(dht_bootstrap_nodes, "dht.libtorrent.org:25401", &session_impl::update_dht_bootstrap_nodes)
|
2017-02-05 04:05:53 +01:00
|
|
|
}});
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-02-05 04:05:53 +01:00
|
|
|
aux::array<bool_setting_entry_t, settings_pack::num_bool_settings> const bool_settings
|
|
|
|
({{
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(allow_multiple_connections_per_ip, false, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
DEPRECATED_SET(ignore_limits_on_local_network, true, &session_impl::update_ignore_rate_limits_on_local_network),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(send_redundant_have, true, nullptr),
|
|
|
|
DEPRECATED_SET(lazy_bitfields, false, nullptr),
|
|
|
|
SET(use_dht_as_fallback, false, nullptr),
|
|
|
|
SET(upnp_ignore_nonrouters, false, nullptr),
|
|
|
|
SET(use_parole_mode, true, nullptr),
|
|
|
|
SET(use_read_cache, true, nullptr),
|
|
|
|
DEPRECATED_SET(use_write_cache, true, nullptr),
|
2017-01-01 17:08:57 +01:00
|
|
|
DEPRECATED_SET(dont_flush_write_cache, false, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(coalesce_reads, false, nullptr),
|
|
|
|
SET(coalesce_writes, false, nullptr),
|
|
|
|
SET(auto_manage_prefer_seeds, false, nullptr),
|
2014-10-06 00:30:09 +02:00
|
|
|
SET(dont_count_slow_torrents, true, &session_impl::update_count_slow),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(close_redundant_connections, true, nullptr),
|
|
|
|
SET(prioritize_partial_pieces, false, nullptr),
|
|
|
|
SET(rate_limit_ip_overhead, true, nullptr),
|
|
|
|
SET(announce_to_all_trackers, false, nullptr),
|
|
|
|
SET(announce_to_all_tiers, false, nullptr),
|
|
|
|
SET(prefer_udp_trackers, true, nullptr),
|
|
|
|
SET(strict_super_seeding, false, nullptr),
|
|
|
|
DEPRECATED_SET(lock_disk_cache, false, nullptr),
|
|
|
|
SET(disable_hash_checks, false, nullptr),
|
|
|
|
SET(allow_i2p_mixed, false, nullptr),
|
2016-09-01 15:42:49 +02:00
|
|
|
DEPRECATED_SET(low_prio_disk, true, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(volatile_read_cache, false, nullptr),
|
2016-07-11 01:25:26 +02:00
|
|
|
DEPRECATED_SET(guided_read_cache, false, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(no_atime_storage, true, nullptr),
|
|
|
|
SET(incoming_starts_queued_torrents, false, nullptr),
|
|
|
|
SET(report_true_downloaded, false, nullptr),
|
|
|
|
SET(strict_end_game_mode, true, nullptr),
|
|
|
|
SET(broadcast_lsd, true, nullptr),
|
|
|
|
SET(enable_outgoing_utp, true, nullptr),
|
|
|
|
SET(enable_incoming_utp, true, nullptr),
|
|
|
|
SET(enable_outgoing_tcp, true, nullptr),
|
|
|
|
SET(enable_incoming_tcp, true, nullptr),
|
|
|
|
SET(ignore_resume_timestamps, false, nullptr),
|
|
|
|
SET(no_recheck_incomplete_resume, false, nullptr),
|
2014-08-31 23:17:32 +02:00
|
|
|
SET(anonymous_mode, false, &session_impl::update_anonymous_mode),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(report_web_seed_downloads, true, &session_impl::update_report_web_seed_downloads),
|
2017-12-16 17:53:20 +01:00
|
|
|
DEPRECATED_SET(rate_limit_utp, true, &session_impl::update_rate_limit_utp),
|
2016-09-01 15:42:49 +02:00
|
|
|
DEPRECATED_SET(announce_double_nat, false, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(seeding_outgoing_connections, true, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(no_connect_privileged_ports, false, &session_impl::update_privileged_ports),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(smooth_connects, true, nullptr),
|
|
|
|
SET(always_send_user_agent, false, nullptr),
|
|
|
|
SET(apply_ip_filter_to_trackers, true, nullptr),
|
2016-09-01 15:42:49 +02:00
|
|
|
DEPRECATED_SET(use_disk_read_ahead, true, nullptr),
|
2017-09-17 10:43:27 +02:00
|
|
|
DEPRECATED_SET(lock_files, false, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
DEPRECATED_SET(contiguous_recv_buffer, true, nullptr),
|
|
|
|
SET(ban_web_seeds, true, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(allow_partial_disk_writes, true, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(force_proxy, false, &session_impl::update_force_proxy),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(support_share_mode, true, nullptr),
|
|
|
|
SET(support_merkle_torrents, true, nullptr),
|
|
|
|
SET(report_redundant_bytes, true, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(listen_system_port_fallback, true, nullptr),
|
2017-08-19 11:04:39 +02:00
|
|
|
DEPRECATED_SET(use_disk_cache_pool, false, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(announce_crypto_support, true, nullptr),
|
|
|
|
SET(enable_upnp, true, &session_impl::update_upnp),
|
|
|
|
SET(enable_natpmp, true, &session_impl::update_natpmp),
|
|
|
|
SET(enable_lsd, true, &session_impl::update_lsd),
|
|
|
|
SET(enable_dht, true, &session_impl::update_dht),
|
|
|
|
SET(prefer_rc4, false, nullptr),
|
|
|
|
SET(proxy_hostnames, true, nullptr),
|
|
|
|
SET(proxy_peer_connections, true, nullptr),
|
|
|
|
SET(auto_sequential, true, &session_impl::update_auto_sequential),
|
|
|
|
SET(proxy_tracker_connections, true, nullptr),
|
2017-11-01 10:51:51 +01:00
|
|
|
SET(enable_ip_notifier, true, &session_impl::update_ip_notifier),
|
2017-02-05 04:05:53 +01:00
|
|
|
}});
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-02-05 04:05:53 +01:00
|
|
|
aux::array<int_setting_entry_t, settings_pack::num_int_settings> const int_settings
|
|
|
|
({{
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(tracker_completion_timeout, 30, nullptr),
|
|
|
|
SET(tracker_receive_timeout, 10, nullptr),
|
|
|
|
SET(stop_tracker_timeout, 5, nullptr),
|
|
|
|
SET(tracker_maximum_response_length, 1024*1024, nullptr),
|
|
|
|
SET(piece_timeout, 20, nullptr),
|
|
|
|
SET(request_timeout, 60, nullptr),
|
|
|
|
SET(request_queue_time, 3, nullptr),
|
|
|
|
SET(max_allowed_in_request_queue, 500, nullptr),
|
|
|
|
SET(max_out_request_queue, 500, nullptr),
|
|
|
|
SET(whole_pieces_threshold, 20, nullptr),
|
|
|
|
SET(peer_timeout, 120, nullptr),
|
|
|
|
SET(urlseed_timeout, 20, nullptr),
|
|
|
|
SET(urlseed_pipeline_size, 5, nullptr),
|
|
|
|
SET(urlseed_wait_retry, 30, nullptr),
|
|
|
|
SET(file_pool_size, 40, nullptr),
|
2015-01-20 07:26:22 +01:00
|
|
|
SET(max_failcount, 3, &session_impl::update_max_failcount),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(min_reconnect_time, 60, nullptr),
|
|
|
|
SET(peer_connect_timeout, 15, nullptr),
|
2016-03-01 07:57:24 +01:00
|
|
|
SET(connection_speed, 10, &session_impl::update_connection_speed),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(inactivity_timeout, 600, nullptr),
|
|
|
|
SET(unchoke_interval, 15, nullptr),
|
|
|
|
SET(optimistic_unchoke_interval, 30, nullptr),
|
|
|
|
SET(num_want, 200, nullptr),
|
|
|
|
SET(initial_picker_threshold, 4, nullptr),
|
|
|
|
SET(allowed_fast_set_size, 5, nullptr),
|
|
|
|
SET(suggest_mode, settings_pack::no_piece_suggestions, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(max_queued_disk_bytes, 1024 * 1024, &session_impl::update_queued_disk_bytes),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(handshake_timeout, 10, nullptr),
|
|
|
|
SET(send_buffer_low_watermark, 10 * 1024, nullptr),
|
|
|
|
SET(send_buffer_watermark, 500 * 1024, nullptr),
|
|
|
|
SET(send_buffer_watermark_factor, 50, nullptr),
|
|
|
|
SET(choking_algorithm, settings_pack::fixed_slots_choker, nullptr),
|
|
|
|
SET(seed_choking_algorithm, settings_pack::round_robin, nullptr),
|
|
|
|
SET(cache_size, 1024, nullptr),
|
2017-08-21 13:36:32 +02:00
|
|
|
DEPRECATED_SET(cache_buffer_chunk_size, 0, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(cache_expiry, 300, nullptr),
|
|
|
|
SET(disk_io_write_mode, settings_pack::enable_os_cache, nullptr),
|
|
|
|
SET(disk_io_read_mode, settings_pack::enable_os_cache, nullptr),
|
|
|
|
SET(outgoing_port, 0, nullptr),
|
|
|
|
SET(num_outgoing_ports, 0, nullptr),
|
2017-02-25 18:16:44 +01:00
|
|
|
SET(peer_tos, 0x20, &session_impl::update_peer_tos),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(active_downloads, 3, &session_impl::trigger_auto_manage),
|
|
|
|
SET(active_seeds, 5, &session_impl::trigger_auto_manage),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(active_checking, 1, &session_impl::trigger_auto_manage),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(active_dht_limit, 88, nullptr),
|
|
|
|
SET(active_tracker_limit, 1600, nullptr),
|
|
|
|
SET(active_lsd_limit, 60, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(active_limit, 15, &session_impl::trigger_auto_manage),
|
2017-03-14 17:55:13 +01:00
|
|
|
DEPRECATED_SET(active_loaded_limit, 0, &session_impl::trigger_auto_manage),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(auto_manage_interval, 30, nullptr),
|
|
|
|
SET(seed_time_limit, 24 * 60 * 60, nullptr),
|
|
|
|
SET(auto_scrape_interval, 1800, nullptr),
|
|
|
|
SET(auto_scrape_min_interval, 300, nullptr),
|
|
|
|
SET(max_peerlist_size, 3000, nullptr),
|
|
|
|
SET(max_paused_peerlist_size, 1000, nullptr),
|
|
|
|
SET(min_announce_interval, 5 * 60, nullptr),
|
|
|
|
SET(auto_manage_startup, 60, nullptr),
|
|
|
|
SET(seeding_piece_quota, 20, nullptr),
|
|
|
|
SET(max_rejects, 50, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(recv_socket_buffer_size, 0, &session_impl::update_socket_buffer_size),
|
|
|
|
SET(send_socket_buffer_size, 0, &session_impl::update_socket_buffer_size),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(max_peer_recv_buffer_size, 2 * 1024 * 1024, nullptr),
|
2017-02-17 06:35:49 +01:00
|
|
|
DEPRECATED_SET(file_checks_delay_per_block, 0, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(read_cache_line_size, 32, nullptr),
|
|
|
|
SET(write_cache_line_size, 16, nullptr),
|
|
|
|
SET(optimistic_disk_retry, 10 * 60, nullptr),
|
|
|
|
SET(max_suggest_pieces, 16, nullptr),
|
|
|
|
SET(local_service_announce_interval, 5 * 60, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(dht_announce_interval, 15 * 60, &session_impl::update_dht_announce_interval),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(udp_tracker_token_expiry, 60, nullptr),
|
2016-07-11 01:25:26 +02:00
|
|
|
DEPRECATED_SET(default_cache_min_age, 1, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(num_optimistic_unchoke_slots, 0, nullptr),
|
|
|
|
SET(default_est_reciprocation_rate, 16000, nullptr),
|
|
|
|
SET(increase_est_reciprocation_rate, 20, nullptr),
|
|
|
|
SET(decrease_est_reciprocation_rate, 3, nullptr),
|
|
|
|
SET(max_pex_peers, 50, nullptr),
|
|
|
|
SET(tick_interval, 500, nullptr),
|
|
|
|
SET(share_mode_target, 3, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(upload_rate_limit, 0, &session_impl::update_upload_rate),
|
|
|
|
SET(download_rate_limit, 0, &session_impl::update_download_rate),
|
|
|
|
DEPRECATED_SET(local_upload_rate_limit, 0, &session_impl::update_local_upload_rate),
|
|
|
|
DEPRECATED_SET(local_download_rate_limit, 0, &session_impl::update_local_download_rate),
|
2016-01-17 21:09:27 +01:00
|
|
|
DEPRECATED_SET(dht_upload_rate_limit, 4000, &session_impl::update_dht_upload_rate_limit),
|
2014-10-23 00:06:56 +02:00
|
|
|
SET(unchoke_slots_limit, 8, &session_impl::update_unchoke_limit),
|
2016-07-09 22:26:26 +02:00
|
|
|
DEPRECATED_SET(half_open_limit, 0, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(connections_limit, 200, &session_impl::update_connections_limit),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(connections_slack, 10, nullptr),
|
|
|
|
SET(utp_target_delay, 100, nullptr),
|
|
|
|
SET(utp_gain_factor, 3000, nullptr),
|
|
|
|
SET(utp_min_timeout, 500, nullptr),
|
|
|
|
SET(utp_syn_resends, 2, nullptr),
|
|
|
|
SET(utp_fin_resends, 2, nullptr),
|
|
|
|
SET(utp_num_resends, 3, nullptr),
|
|
|
|
SET(utp_connect_timeout, 3000, nullptr),
|
|
|
|
SET(utp_delayed_ack, 0, nullptr),
|
|
|
|
SET(utp_loss_multiplier, 50, nullptr),
|
|
|
|
SET(mixed_mode_algorithm, settings_pack::peer_proportional, nullptr),
|
|
|
|
SET(listen_queue_size, 5, nullptr),
|
|
|
|
SET(torrent_connect_boost, 10, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(alert_queue_size, 1000, &session_impl::update_alert_queue_size),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(max_metadata_size, 3 * 1024 * 10240, nullptr),
|
|
|
|
DEPRECATED_SET(hashing_threads, 1, nullptr),
|
|
|
|
SET(checking_mem_usage, 256, nullptr),
|
|
|
|
SET(predictive_piece_announce, 0, nullptr),
|
2014-07-06 21:18:00 +02:00
|
|
|
SET(aio_threads, 4, &session_impl::update_disk_threads),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(aio_max, 300, nullptr),
|
|
|
|
SET(network_threads, 0, nullptr),
|
2016-03-19 21:02:46 +01:00
|
|
|
DEPRECATED_SET(ssl_listen, 0, &session_impl::update_ssl_listen),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(tracker_backoff, 250, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(share_ratio_limit, 200, nullptr),
|
|
|
|
SET(seed_time_ratio_limit, 700, nullptr),
|
|
|
|
SET(peer_turnover, 4, nullptr),
|
|
|
|
SET(peer_turnover_cutoff, 90, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(peer_turnover_interval, 300, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(connect_seed_every_n_download, 10, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(max_http_recv_buffer_size, 4*1024*204, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(max_retry_port_bind, 10, nullptr),
|
2017-07-26 06:33:10 +02:00
|
|
|
SET(alert_mask, int(static_cast<std::uint32_t>(alert::error_notification)), &session_impl::update_alert_mask),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(out_enc_policy, settings_pack::pe_enabled, nullptr),
|
|
|
|
SET(in_enc_policy, settings_pack::pe_enabled, nullptr),
|
|
|
|
SET(allowed_enc_level, settings_pack::pe_both, nullptr),
|
2016-07-09 22:26:26 +02:00
|
|
|
SET(inactive_down_rate, 2048, nullptr),
|
|
|
|
SET(inactive_up_rate, 2048, nullptr),
|
2016-09-21 08:49:23 +02:00
|
|
|
SET(proxy_type, settings_pack::none, &session_impl::update_proxy),
|
|
|
|
SET(proxy_port, 0, &session_impl::update_proxy),
|
|
|
|
SET(i2p_port, 0, &session_impl::update_i2p_bridge),
|
2017-02-26 06:48:12 +01:00
|
|
|
SET(cache_size_volatile, 256, nullptr),
|
2017-09-28 10:11:20 +02:00
|
|
|
SET(urlseed_max_request_bytes, 16 * 1024 * 1024, nullptr),
|
2017-02-26 06:48:12 +01:00
|
|
|
SET(web_seed_name_lookup_retry, 1800, nullptr),
|
2017-04-09 00:24:50 +02:00
|
|
|
SET(close_file_interval, CLOSE_FILE_INTERVAL, nullptr),
|
2017-03-18 20:53:07 +01:00
|
|
|
SET(max_web_seed_connections, 3, nullptr),
|
2017-04-05 00:23:37 +02:00
|
|
|
SET(resolver_cache_timeout, 1200, &session_impl::update_resolver_cache_timeout),
|
2017-02-05 04:05:53 +01:00
|
|
|
}});
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
#undef SET
|
2017-04-02 21:49:20 +02:00
|
|
|
#undef DEPRECATED_SET
|
2014-07-22 07:35:05 +02:00
|
|
|
|
2015-04-19 08:28:21 +02:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
int setting_by_name(std::string const& key)
|
|
|
|
{
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < str_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != str_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
return settings_pack::string_type_base + k;
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < int_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != int_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
return settings_pack::int_type_base + k;
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < bool_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != bool_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
return settings_pack::bool_type_base + k;
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* name_for_setting(int s)
|
|
|
|
{
|
|
|
|
switch (s & settings_pack::type_mask)
|
|
|
|
{
|
|
|
|
case settings_pack::string_type_base:
|
|
|
|
return str_settings[s - settings_pack::string_type_base].name;
|
|
|
|
case settings_pack::int_type_base:
|
|
|
|
return int_settings[s - settings_pack::int_type_base].name;
|
|
|
|
case settings_pack::bool_type_base:
|
|
|
|
return bool_settings[s - settings_pack::bool_type_base].name;
|
|
|
|
};
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2016-09-11 07:58:48 +02:00
|
|
|
settings_pack load_pack_from_dict(bdecode_node const& settings)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2016-09-11 07:58:48 +02:00
|
|
|
settings_pack pack;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2015-03-12 06:20:12 +01:00
|
|
|
for (int i = 0; i < settings.dict_size(); ++i)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2016-08-13 13:04:53 +02:00
|
|
|
string_view key;
|
2015-03-12 06:20:12 +01:00
|
|
|
bdecode_node val;
|
2016-06-20 17:32:06 +02:00
|
|
|
std::tie(key, val) = settings.dict_at(i);
|
2015-03-12 06:20:12 +01:00
|
|
|
switch (val.type())
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2015-03-12 06:20:12 +01:00
|
|
|
case bdecode_node::dict_t:
|
|
|
|
case bdecode_node::list_t:
|
2014-07-06 21:18:00 +02:00
|
|
|
continue;
|
2015-03-12 06:20:12 +01:00
|
|
|
case bdecode_node::int_t:
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
bool found = false;
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < int_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != int_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
pack.set_int(settings_pack::int_type_base + k, int(val.int_value()));
|
2014-07-06 21:18:00 +02:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (found) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < bool_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != bool_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
pack.set_bool(settings_pack::bool_type_base + k, val.int_value() != 0);
|
2014-07-06 21:18:00 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2015-03-12 06:20:12 +01:00
|
|
|
case bdecode_node::string_t:
|
2017-02-05 04:05:53 +01:00
|
|
|
for (int k = 0; k < str_settings.end_index(); ++k)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
if (key != str_settings[k].name) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
pack.set_str(settings_pack::string_type_base + k, val.string_value().to_string());
|
2014-07-06 21:18:00 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2015-03-12 06:20:12 +01:00
|
|
|
case bdecode_node::none_t:
|
2014-07-06 21:18:00 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pack;
|
|
|
|
}
|
|
|
|
|
|
|
|
void save_settings_to_dict(aux::session_settings const& s, entry::dictionary_type& sett)
|
|
|
|
{
|
|
|
|
// loop over all settings that differ from default
|
|
|
|
for (int i = 0; i < settings_pack::num_string_settings; ++i)
|
|
|
|
{
|
2017-02-05 18:51:48 +01:00
|
|
|
if (ensure_string(str_settings[i].default_value) == s.m_strings[std::size_t(i)]) continue;
|
2017-02-05 04:05:53 +01:00
|
|
|
sett[str_settings[i].name] = s.m_strings[std::size_t(i)];
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_int_settings; ++i)
|
|
|
|
{
|
2017-02-05 04:05:53 +01:00
|
|
|
if (int_settings[i].default_value == s.m_ints[std::size_t(i)]) continue;
|
|
|
|
sett[int_settings[i].name] = s.m_ints[std::size_t(i)];
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_bool_settings; ++i)
|
|
|
|
{
|
2017-02-05 04:05:53 +01:00
|
|
|
if (bool_settings[i].default_value == s.m_bools[std::size_t(i)]) continue;
|
|
|
|
sett[bool_settings[i].name] = s.m_bools[std::size_t(i)];
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-30 16:04:03 +01:00
|
|
|
void run_all_updates(aux::session_impl& ses)
|
|
|
|
{
|
2018-03-22 17:01:38 +01:00
|
|
|
using fun_t = void (aux::session_impl::*)();
|
2017-11-30 16:04:03 +01:00
|
|
|
for (int i = 0; i < settings_pack::num_string_settings; ++i)
|
|
|
|
{
|
|
|
|
fun_t const& f = str_settings[i].fun;
|
|
|
|
if (f) (ses.*f)();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_int_settings; ++i)
|
|
|
|
{
|
|
|
|
fun_t const& f = int_settings[i].fun;
|
|
|
|
if (f) (ses.*f)();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_bool_settings; ++i)
|
|
|
|
{
|
|
|
|
fun_t const& f = bool_settings[i].fun;
|
|
|
|
if (f) (ses.*f)();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void initialize_default_settings(aux::session_settings& s)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < settings_pack::num_string_settings; ++i)
|
|
|
|
{
|
2016-07-09 22:26:26 +02:00
|
|
|
if (str_settings[i].default_value == nullptr) continue;
|
2014-07-06 21:18:00 +02:00
|
|
|
s.set_str(settings_pack::string_type_base + i, str_settings[i].default_value);
|
|
|
|
TORRENT_ASSERT(s.get_str(settings_pack::string_type_base + i) == str_settings[i].default_value);
|
|
|
|
}
|
2015-06-07 15:23:04 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
for (int i = 0; i < settings_pack::num_int_settings; ++i)
|
|
|
|
{
|
|
|
|
s.set_int(settings_pack::int_type_base + i, int_settings[i].default_value);
|
|
|
|
TORRENT_ASSERT(s.get_int(settings_pack::int_type_base + i) == int_settings[i].default_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_bool_settings; ++i)
|
|
|
|
{
|
|
|
|
s.set_bool(settings_pack::bool_type_base + i, bool_settings[i].default_value);
|
|
|
|
TORRENT_ASSERT(s.get_bool(settings_pack::bool_type_base + i) == bool_settings[i].default_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-05 09:13:26 +01:00
|
|
|
settings_pack default_settings()
|
|
|
|
{
|
|
|
|
settings_pack ret;
|
|
|
|
// TODO: it would be nice to reserve() these vectors up front
|
|
|
|
for (int i = 0; i < settings_pack::num_string_settings; ++i)
|
|
|
|
{
|
2017-02-05 18:51:48 +01:00
|
|
|
if (str_settings[i].default_value == nullptr) continue;
|
2017-02-05 09:13:26 +01:00
|
|
|
ret.set_str(settings_pack::string_type_base + i, str_settings[i].default_value);
|
|
|
|
}
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-02-05 09:13:26 +01:00
|
|
|
for (int i = 0; i < settings_pack::num_int_settings; ++i)
|
|
|
|
{
|
|
|
|
ret.set_int(settings_pack::int_type_base + i, int_settings[i].default_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < settings_pack::num_bool_settings; ++i)
|
|
|
|
{
|
|
|
|
ret.set_bool(settings_pack::bool_type_base + i, bool_settings[i].default_value);
|
|
|
|
}
|
|
|
|
return ret;
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void apply_pack(settings_pack const* pack, aux::session_settings& sett
|
|
|
|
, aux::session_impl* ses)
|
|
|
|
{
|
2018-03-22 17:01:38 +01:00
|
|
|
using fun_t = void (aux::session_impl::*)();
|
2014-07-06 21:18:00 +02:00
|
|
|
std::vector<fun_t> callbacks;
|
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
for (auto const& p : pack->m_strings)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
// disregard setting indices that are not string types
|
2016-09-09 01:13:47 +02:00
|
|
|
if ((p.first & settings_pack::type_mask) != settings_pack::string_type_base)
|
2014-07-06 21:18:00 +02:00
|
|
|
continue;
|
2015-08-13 02:18:47 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// ignore settings that are out of bounds
|
2016-09-09 01:13:47 +02:00
|
|
|
int const index = p.first & settings_pack::index_mask;
|
2016-04-29 18:01:33 +02:00
|
|
|
TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_string_settings);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (index < 0 || index >= settings_pack::num_string_settings)
|
|
|
|
continue;
|
|
|
|
|
2016-09-21 07:06:07 +02:00
|
|
|
// if the value did not change, don't call the update callback
|
2016-09-12 03:01:03 +02:00
|
|
|
if (sett.get_str(p.first) == p.second) continue;
|
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
sett.set_str(p.first, p.second);
|
2016-04-29 18:01:33 +02:00
|
|
|
str_setting_entry_t const& sa = str_settings[index];
|
2016-08-23 03:38:57 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
if (sa.fun && ses
|
|
|
|
&& std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
|
|
|
|
callbacks.push_back(sa.fun);
|
|
|
|
}
|
2016-03-15 06:55:36 +01:00
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
for (auto const& p : pack->m_ints)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2015-09-08 21:15:51 +02:00
|
|
|
// disregard setting indices that are not int types
|
2016-09-09 01:13:47 +02:00
|
|
|
if ((p.first & settings_pack::type_mask) != settings_pack::int_type_base)
|
2014-07-06 21:18:00 +02:00
|
|
|
continue;
|
2016-03-15 06:55:36 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// ignore settings that are out of bounds
|
2016-09-09 01:13:47 +02:00
|
|
|
int const index = p.first & settings_pack::index_mask;
|
2016-04-29 18:01:33 +02:00
|
|
|
TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_int_settings);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (index < 0 || index >= settings_pack::num_int_settings)
|
|
|
|
continue;
|
|
|
|
|
2016-09-21 07:06:07 +02:00
|
|
|
// if the value did not change, don't call the update callback
|
2016-09-12 03:01:03 +02:00
|
|
|
if (sett.get_int(p.first) == p.second) continue;
|
2016-08-23 03:38:57 +02:00
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
sett.set_int(p.first, p.second);
|
2016-04-29 18:01:33 +02:00
|
|
|
int_setting_entry_t const& sa = int_settings[index];
|
2014-07-06 21:18:00 +02:00
|
|
|
if (sa.fun && ses
|
|
|
|
&& std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
|
|
|
|
callbacks.push_back(sa.fun);
|
|
|
|
}
|
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
for (auto const& p : pack->m_bools)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2015-09-08 21:15:51 +02:00
|
|
|
// disregard setting indices that are not bool types
|
2016-09-09 01:13:47 +02:00
|
|
|
if ((p.first & settings_pack::type_mask) != settings_pack::bool_type_base)
|
2014-07-06 21:18:00 +02:00
|
|
|
continue;
|
2016-03-15 06:55:36 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// ignore settings that are out of bounds
|
2016-09-09 01:13:47 +02:00
|
|
|
int const index = p.first & settings_pack::index_mask;
|
2016-04-29 18:01:33 +02:00
|
|
|
TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_bool_settings);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (index < 0 || index >= settings_pack::num_bool_settings)
|
|
|
|
continue;
|
|
|
|
|
2016-09-21 07:06:07 +02:00
|
|
|
// if the value did not change, don't call the update callback
|
2016-09-12 03:01:03 +02:00
|
|
|
if (sett.get_bool(p.first) == p.second) continue;
|
2016-08-23 03:38:57 +02:00
|
|
|
|
2016-09-09 01:13:47 +02:00
|
|
|
sett.set_bool(p.first, p.second);
|
2016-04-29 18:01:33 +02:00
|
|
|
bool_setting_entry_t const& sa = bool_settings[index];
|
2014-07-06 21:18:00 +02:00
|
|
|
if (sa.fun && ses
|
|
|
|
&& std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
|
|
|
|
callbacks.push_back(sa.fun);
|
|
|
|
}
|
|
|
|
|
|
|
|
// call the callbacks once all the settings have been applied, and
|
|
|
|
// only once per callback
|
2016-09-09 01:13:47 +02:00
|
|
|
for (auto const& f : callbacks)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
(ses->*f)();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
void settings_pack::set_str(int const name, std::string val)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT((name & type_mask) == string_type_base);
|
|
|
|
if ((name & type_mask) != string_type_base) return;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, std::string> v(aux::numeric_cast<std::uint16_t>(name), std::move(val));
|
2016-08-13 13:04:53 +02:00
|
|
|
insort_replace(m_strings, std::move(v));
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
void settings_pack::set_int(int const name, int const val)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT((name & type_mask) == int_type_base);
|
|
|
|
if ((name & type_mask) != int_type_base) return;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, int> v(aux::numeric_cast<std::uint16_t>(name), val);
|
2014-07-06 21:18:00 +02:00
|
|
|
insort_replace(m_ints, v);
|
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
void settings_pack::set_bool(int const name, bool const val)
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT((name & type_mask) == bool_type_base);
|
|
|
|
if ((name & type_mask) != bool_type_base) return;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, bool> v(aux::numeric_cast<std::uint16_t>(name), val);
|
2014-07-06 21:18:00 +02:00
|
|
|
insort_replace(m_bools, v);
|
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
bool settings_pack::has_val(int const name) const
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
switch (name & type_mask)
|
|
|
|
{
|
|
|
|
case string_type_base:
|
|
|
|
{
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_strings.size() == settings_pack::num_string_settings)
|
|
|
|
return true;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, std::string> v(aux::numeric_cast<std::uint16_t>(name), std::string());
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_strings.begin(), m_strings.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<std::string>);
|
2014-07-06 21:18:00 +02:00
|
|
|
return i != m_strings.end() && i->first == name;
|
|
|
|
}
|
|
|
|
case int_type_base:
|
|
|
|
{
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_ints.size() == settings_pack::num_int_settings)
|
|
|
|
return true;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, int> v(aux::numeric_cast<std::uint16_t>(name), 0);
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_ints.begin(), m_ints.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<int>);
|
2014-07-06 21:18:00 +02:00
|
|
|
return i != m_ints.end() && i->first == name;
|
|
|
|
}
|
|
|
|
case bool_type_base:
|
|
|
|
{
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_bools.size() == settings_pack::num_bool_settings)
|
|
|
|
return true;
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, bool> v(aux::numeric_cast<std::uint16_t>(name), false);
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_bools.begin(), m_bools.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<bool>);
|
2014-07-06 21:18:00 +02:00
|
|
|
return i != m_bools.end() && i->first == name;
|
|
|
|
}
|
|
|
|
}
|
2016-05-02 18:36:21 +02:00
|
|
|
TORRENT_ASSERT_FAIL();
|
2014-07-06 21:18:00 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
std::string const& settings_pack::get_str(int name) const
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
2016-08-13 13:04:53 +02:00
|
|
|
static std::string const empty;
|
2014-07-06 21:18:00 +02:00
|
|
|
TORRENT_ASSERT((name & type_mask) == string_type_base);
|
2016-08-13 13:04:53 +02:00
|
|
|
if ((name & type_mask) != string_type_base) return empty;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_strings.size() == settings_pack::num_string_settings)
|
|
|
|
{
|
2015-06-07 15:23:04 +02:00
|
|
|
TORRENT_ASSERT(m_strings[name & index_mask].first == name);
|
|
|
|
return m_strings[name & index_mask].second;
|
2015-06-07 06:23:30 +02:00
|
|
|
}
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, std::string> v(aux::numeric_cast<std::uint16_t>(name), std::string());
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_strings.begin(), m_strings.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<std::string>);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (i != m_strings.end() && i->first == name) return i->second;
|
2016-08-13 13:04:53 +02:00
|
|
|
return empty;
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int settings_pack::get_int(int name) const
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT((name & type_mask) == int_type_base);
|
|
|
|
if ((name & type_mask) != int_type_base) return 0;
|
|
|
|
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_ints.size() == settings_pack::num_int_settings)
|
|
|
|
{
|
2015-06-07 15:23:04 +02:00
|
|
|
TORRENT_ASSERT(m_ints[name & index_mask].first == name);
|
|
|
|
return m_ints[name & index_mask].second;
|
2015-06-07 06:23:30 +02:00
|
|
|
}
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, int> v(aux::numeric_cast<std::uint16_t>(name), 0);
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_ints.begin(), m_ints.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<int>);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (i != m_ints.end() && i->first == name) return i->second;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool settings_pack::get_bool(int name) const
|
|
|
|
{
|
|
|
|
TORRENT_ASSERT((name & type_mask) == bool_type_base);
|
|
|
|
if ((name & type_mask) != bool_type_base) return false;
|
|
|
|
|
2015-06-07 06:23:30 +02:00
|
|
|
// this is an optimization. If the settings pack is complete,
|
|
|
|
// i.e. has every key, we don't need to search, it's just a lookup
|
|
|
|
if (m_bools.size() == settings_pack::num_bool_settings)
|
|
|
|
{
|
2015-06-07 15:23:04 +02:00
|
|
|
TORRENT_ASSERT(m_bools[name & index_mask].first == name);
|
|
|
|
return m_bools[name & index_mask].second;
|
2015-06-07 06:23:30 +02:00
|
|
|
}
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, bool> v(aux::numeric_cast<std::uint16_t>(name), false);
|
2016-08-13 13:04:53 +02:00
|
|
|
auto i = std::lower_bound(m_bools.begin(), m_bools.end(), v
|
2015-01-03 17:52:22 +01:00
|
|
|
, &compare_first<bool>);
|
2014-07-06 21:18:00 +02:00
|
|
|
if (i != m_bools.end() && i->first == name) return i->second;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void settings_pack::clear()
|
|
|
|
{
|
|
|
|
m_strings.clear();
|
|
|
|
m_ints.clear();
|
|
|
|
m_bools.clear();
|
|
|
|
}
|
2017-01-15 07:21:52 +01:00
|
|
|
|
|
|
|
void settings_pack::clear(int const name)
|
|
|
|
{
|
|
|
|
switch (name & type_mask)
|
|
|
|
{
|
|
|
|
case string_type_base:
|
|
|
|
{
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, std::string> v(aux::numeric_cast<std::uint16_t>(name), std::string());
|
2017-02-05 04:05:53 +01:00
|
|
|
auto const i = std::lower_bound(m_strings.begin(), m_strings.end()
|
|
|
|
, v, &compare_first<std::string>);
|
2017-01-15 07:21:52 +01:00
|
|
|
if (i != m_strings.end() && i->first == name) m_strings.erase(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case int_type_base:
|
|
|
|
{
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, int> v(aux::numeric_cast<std::uint16_t>(name), 0);
|
2017-02-05 04:05:53 +01:00
|
|
|
auto const i = std::lower_bound(m_ints.begin(), m_ints.end()
|
|
|
|
, v, &compare_first<int>);
|
2017-01-15 07:21:52 +01:00
|
|
|
if (i != m_ints.end() && i->first == name) m_ints.erase(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case bool_type_base:
|
|
|
|
{
|
2017-04-24 02:52:37 +02:00
|
|
|
std::pair<std::uint16_t, bool> v(aux::numeric_cast<std::uint16_t>(name), false);
|
2017-02-05 04:05:53 +01:00
|
|
|
auto const i = std::lower_bound(m_bools.begin(), m_bools.end()
|
|
|
|
, v, &compare_first<bool>);
|
2017-01-15 07:21:52 +01:00
|
|
|
if (i != m_bools.end() && i->first == name) m_bools.erase(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-06 21:18:00 +02:00
|
|
|
}
|