diff --git a/bindings/python/src/create_torrent.cpp b/bindings/python/src/create_torrent.cpp index bcb0c1bdb..37d819bfa 100644 --- a/bindings/python/src/create_torrent.cpp +++ b/bindings/python/src/create_torrent.cpp @@ -121,11 +121,11 @@ namespace void bind_create_torrent() { void (file_storage::*add_file0)(std::string const&, std::int64_t - , int, std::time_t, std::string const&) = &file_storage::add_file; + , int, std::time_t, string_view) = &file_storage::add_file; #if !defined TORRENT_NO_DEPRECATE #if TORRENT_USE_WSTRING void (file_storage::*add_file1)(std::wstring const&, std::int64_t - , int, std::time_t, std::string const&) = &file_storage::add_file; + , int, std::time_t, string_view) = &file_storage::add_file; #endif // TORRENT_USE_WSTRING #endif // TORRENT_NO_DEPRECATE diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 46d0d218d..203c15d46 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -229,7 +229,7 @@ namespace if (params.has_key("info_hash")) - p.info_hash = sha1_hash(bytes(extract(params["info_hash"])).arr); + p.info_hash = sha1_hash(bytes(extract(params["info_hash"])).arr.data()); if (params.has_key("name")) p.name = extract(params["name"]); p.save_path = extract(params["save_path"]); diff --git a/bindings/python/src/torrent_info.cpp b/bindings/python/src/torrent_info.cpp index 25f386b35..a68cf4998 100644 --- a/bindings/python/src/torrent_info.cpp +++ b/bindings/python/src/torrent_info.cpp @@ -91,7 +91,7 @@ namespace { std::vector h; for (int i = 0, e = int(len(hashes)); i < e; ++i) - h.push_back(sha1_hash(bytes(extract(hashes[i])).arr)); + h.push_back(sha1_hash(bytes(extract(hashes[i])).arr.data())); ti.set_merkle_tree(h); } diff --git a/examples/client_test.cpp b/examples/client_test.cpp index a53936c29..be44fb4b2 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -2038,7 +2038,7 @@ int main(int argc, char* argv[]) if (show_pad_files) { std::snprintf(str, sizeof(str), "\x1b[34m%-70s %s\x1b[0m\x1b[K\n" - , ti->files().file_name(i).c_str() + , ti->files().file_name(i).to_string().c_str() , add_suffix(ti->files().file_size(i)).c_str()); out += str; pos += 1; @@ -2051,7 +2051,7 @@ int main(int argc, char* argv[]) bool complete = file_progress[i] == ti->files().file_size(i); - std::string title = ti->files().file_name(i); + std::string title = ti->files().file_name(i).to_string(); if (!complete) { std::snprintf(str, sizeof(str), " (%.1f%%)", progress / 10.f); diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index e1cfc71bc..0f7a1f132 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -126,6 +126,7 @@ nobase_include_HEADERS = \ storage.hpp \ storage_defs.hpp \ tailqueue.hpp \ + string_view.hpp \ string_util.hpp \ time.hpp \ timestamp_history.hpp \ diff --git a/include/libtorrent/aux_/escape_string.hpp b/include/libtorrent/aux_/escape_string.hpp index 98f762fe9..a3e163de8 100644 --- a/include/libtorrent/aux_/escape_string.hpp +++ b/include/libtorrent/aux_/escape_string.hpp @@ -52,6 +52,8 @@ namespace libtorrent }; } + + // TODO: 3 this should probably take a string_ref TORRENT_EXTRA_EXPORT std::string unescape_string(std::string const& s, error_code& ec); // replaces all disallowed URL characters by their %-encoding TORRENT_EXTRA_EXPORT std::string escape_string(const char* str, int len); diff --git a/include/libtorrent/aux_/session_settings.hpp b/include/libtorrent/aux_/session_settings.hpp index fd9ce855e..c9ba58961 100644 --- a/include/libtorrent/aux_/session_settings.hpp +++ b/include/libtorrent/aux_/session_settings.hpp @@ -54,8 +54,8 @@ namespace libtorrent { namespace aux friend TORRENT_EXTRA_EXPORT void libtorrent::save_settings_to_dict( aux::session_settings const& s, entry::dictionary_type& sett); - void set_str(int name, std::string const& value) - { set(m_strings, name, value, settings_pack::string_type_base); } + void set_str(int name, std::string value) + { set(m_strings, name, std::move(value), settings_pack::string_type_base); } void set_int(int name, int value) { set(m_ints, name, value, settings_pack::int_type_base); } void set_bool(int name, bool value) @@ -73,13 +73,13 @@ namespace libtorrent { namespace aux private: template - void set(std::array& arr, int const name, T const& val, int const type) const + void set(std::array& arr, int const name, T val, int const type) const { TORRENT_ASSERT((name & settings_pack::type_mask) == type); if ((name & settings_pack::type_mask) != type) return; size_t const index = name & settings_pack::index_mask; TORRENT_ASSERT(index < N); - arr[index] = val; + arr[index] = std::move(val); } template @@ -99,9 +99,6 @@ namespace libtorrent { namespace aux std::array m_bools; }; -#undef GET -#undef SET - } } #endif diff --git a/include/libtorrent/bdecode.hpp b/include/libtorrent/bdecode.hpp index b09fab155..876689b31 100644 --- a/include/libtorrent/bdecode.hpp +++ b/include/libtorrent/bdecode.hpp @@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/assert.hpp" #include "libtorrent/span.hpp" +#include "libtorrent/string_view.hpp" /* @@ -290,8 +291,8 @@ struct TORRENT_EXPORT bdecode_node // in the list at index ``i``. ``i`` may not be greater than or equal to the // size of the list. ``size()`` returns the size of the list. bdecode_node list_at(int i) const; - std::string list_string_value_at(int i - , char const* default_val = ""); + string_view list_string_value_at(int i + , string_view default_val = string_view()); std::int64_t list_int_value_at(int i , std::int64_t default_val = 0); int list_size() const; @@ -306,17 +307,15 @@ struct TORRENT_EXPORT bdecode_node // Functions with the ``_value`` suffix return the value of the node // directly, rather than the nodes. In case the node is not found, or it has // a different type, a default value is returned (which can be specified). - bdecode_node dict_find(std::string key) const; - bdecode_node dict_find(char const* key) const; - std::pair dict_at(int i) const; - bdecode_node dict_find_dict(std::string key) const; - bdecode_node dict_find_dict(char const* key) const; - bdecode_node dict_find_list(char const* key) const; - bdecode_node dict_find_string(char const* key) const; - bdecode_node dict_find_int(char const* key) const; - std::string dict_find_string_value(char const* key - , char const* default_value = "") const; - std::int64_t dict_find_int_value(char const* key + bdecode_node dict_find(string_view key) const; + std::pair dict_at(int i) const; + bdecode_node dict_find_dict(string_view key) const; + bdecode_node dict_find_list(string_view key) const; + bdecode_node dict_find_string(string_view key) const; + bdecode_node dict_find_int(string_view key) const; + string_view dict_find_string_value(string_view key + , string_view default_value = string_view()) const; + std::int64_t dict_find_int_value(string_view key , std::int64_t default_val = 0) const; int dict_size() const; @@ -327,7 +326,7 @@ struct TORRENT_EXPORT bdecode_node // these functions are only valid if ``type()`` == ``string_t``. They return // the string values. Note that ``string_ptr()`` is *not* 0-terminated. // ``string_length()`` returns the number of bytes in the string. - std::string string_value() const; + string_view string_value() const; char const* string_ptr() const; int string_length() const; diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 7890fc470..41274ca32 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "libtorrent/config.hpp" +#include "libtorrent/string_view.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" @@ -160,18 +161,17 @@ namespace libtorrent // internal used by create_torrent.hpp TORRENT_EXTRA_EXPORT std::string filename(std::string const& f); - TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs - , std::string const& rhs); + TORRENT_EXTRA_EXPORT std::string combine_path(string_view lhs + , string_view rhs); TORRENT_EXTRA_EXPORT void append_path(std::string& branch - , std::string const& leaf); - TORRENT_EXTRA_EXPORT void append_path(std::string& branch - , char const* str, int len); + , string_view leaf); + // internal used by create_torrent.hpp - TORRENT_EXTRA_EXPORT std::string complete(std::string const& f); - TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f); + TORRENT_EXTRA_EXPORT std::string complete(string_view f); + TORRENT_EXTRA_EXPORT bool is_complete(string_view f); TORRENT_EXTRA_EXPORT std::string current_working_directory(); #if TORRENT_USE_UNC_PATHS - TORRENT_EXTRA_EXPORT std::string canonicalize_path(std::string const& f); + TORRENT_EXTRA_EXPORT std::string canonicalize_path(string_view f); #endif // TODO: move this into a separate header file, TU pair diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index 0942ce883..289040216 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/assert.hpp" #include "libtorrent/peer_request.hpp" #include "libtorrent/peer_id.hpp" +#include "libtorrent/string_view.hpp" namespace libtorrent { @@ -119,30 +120,15 @@ namespace libtorrent friend class torrent_info; #endif - internal_file_entry() - : offset(0) - , symlink_index(not_a_symlink) - , no_root_dir(false) - , size(0) - , name_len(name_is_owned) - , pad_file(false) - , hidden_attribute(false) - , executable_attribute(false) - , symlink_attribute(false) - , name(nullptr) - , path_index(-1) - {} - + internal_file_entry(); internal_file_entry(internal_file_entry const& fe); internal_file_entry& operator=(internal_file_entry const& fe); - + internal_file_entry(internal_file_entry&& fe); + internal_file_entry& operator=(internal_file_entry&& fe); ~internal_file_entry(); void set_name(char const* n, bool borrow_string = false, int string_len = 0); - std::string filename() const; - char const* filename_ptr() const { return name; } - int filename_len() const - { return name_len == name_is_owned?int(strlen(name)):int(name_len); } + string_view filename() const; enum { name_is_owned = (1<<12)-1, @@ -223,8 +209,10 @@ namespace libtorrent file_storage(); // hidden ~file_storage(); - file_storage(file_storage const& f); + file_storage(file_storage const&); file_storage& operator=(file_storage const&); + file_storage(file_storage&&); + file_storage& operator=(file_storage&&); // returns true if the piece length has been initialized // on the file_storage. This is typically taken as a proxy @@ -297,9 +285,9 @@ namespace libtorrent void add_file_borrow(char const* filename, int filename_len , std::string const& path, std::int64_t file_size , std::uint32_t file_flags = 0, char const* filehash = 0 - , std::int64_t mtime = 0, std::string const& symlink_path = ""); + , std::int64_t mtime = 0, string_view symlink_path = string_view()); void add_file(std::string const& path, std::int64_t file_size, int file_flags = 0 - , std::time_t mtime = 0, std::string const& symlink_path = ""); + , std::time_t mtime = 0, string_view symlink_path = string_view()); // renames the file at ``index`` to ``new_filename``. Keep in mind // that filenames are expected to be UTF-8 encoded. @@ -315,7 +303,7 @@ namespace libtorrent // and pass in utf8 strings TORRENT_DEPRECATED void add_file(std::wstring const& p, std::int64_t size, int flags = 0 - , std::time_t mtime = 0, std::string const& s_p = ""); + , std::time_t mtime = 0, string_view s_p = ""); TORRENT_DEPRECATED void rename_file(int index, std::wstring const& new_filename); TORRENT_DEPRECATED @@ -478,7 +466,7 @@ namespace libtorrent std::string const& symlink(int index) const; time_t mtime(int index) const; std::string file_path(int index, std::string const& save_path = "") const; - std::string file_name(int index) const; + string_view file_name(int index) const; std::int64_t file_size(int index) const; bool pad_file_at(int index) const; std::int64_t file_offset(int index) const; diff --git a/include/libtorrent/kademlia/find_data.hpp b/include/libtorrent/kademlia/find_data.hpp index 62a48e1ec..ccd33e7df 100644 --- a/include/libtorrent/kademlia/find_data.hpp +++ b/include/libtorrent/kademlia/find_data.hpp @@ -68,7 +68,7 @@ struct find_data : traversal_algorithm find_data(node& node, node_id target , nodes_callback const& ncallback); - void got_write_token(node_id const& n, std::string const& write_token); + void got_write_token(node_id const& n, std::string write_token); virtual void start(); diff --git a/include/libtorrent/kademlia/node.hpp b/include/libtorrent/kademlia/node.hpp index 3e7eb43c1..c2993dadd 100644 --- a/include/libtorrent/kademlia/node.hpp +++ b/include/libtorrent/kademlia/node.hpp @@ -54,6 +54,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "libtorrent/socket.hpp" @@ -157,7 +158,7 @@ public: , boost::function f , boost::function data_cb); - bool verify_token(std::string const& token, sha1_hash const& info_hash + bool verify_token(string_view token, sha1_hash const& info_hash , udp::endpoint const& addr) const; std::string generate_token(udp::endpoint const& addr, sha1_hash const& info_hash); diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 40d391c6e..5a2fe27a8 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -34,12 +34,12 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_SETTINGS_PACK_HPP_INCLUDED #include "libtorrent/entry.hpp" +#include "libtorrent/string_view.hpp" + #include #include "libtorrent/aux_/disable_warnings_push.hpp" - #include - #include "libtorrent/aux_/disable_warnings_pop.hpp" // OVERVIEW @@ -97,7 +97,7 @@ namespace libtorrent bool has_val(int name) const; void clear(); - std::string get_str(int name) const; + std::string const& get_str(int name) const; int get_int(int name) const; bool get_bool(int name) const; diff --git a/include/libtorrent/sha1_hash.hpp b/include/libtorrent/sha1_hash.hpp index c186b61e2..e880d8915 100644 --- a/include/libtorrent/sha1_hash.hpp +++ b/include/libtorrent/sha1_hash.hpp @@ -95,15 +95,22 @@ namespace libtorrent if (s == 0) clear(); else std::memcpy(m_number, s, size()); } +#ifndef TORRENT_NO_DEPRECATE + TORRENT_DEPRECATED explicit sha1_hash(std::string const& s) + { + assign(s.data()); + } +#endif + explicit sha1_hash(span s) { assign(s); } - void assign(std::string const& s) + void assign(span s) { TORRENT_ASSERT(s.size() >= 20); size_t const sl = s.size() < size() ? s.size() : size(); - std::memcpy(m_number, s.c_str(), sl); + std::memcpy(m_number, s.data(), sl); } void assign(char const* str) { std::memcpy(m_number, str, size()); } diff --git a/include/libtorrent/string_view.hpp b/include/libtorrent/string_view.hpp new file mode 100644 index 000000000..80b451b5c --- /dev/null +++ b/include/libtorrent/string_view.hpp @@ -0,0 +1,55 @@ +/* + +Copyright (c) 2016, Arvid Norberg +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. + +*/ + +#ifndef TORRENT_STRING_VIEW_HPP_INCLUDED +#define TORRENT_STRING_VIEW_HPP_INCLUDED + +#include + +#include "libtorrent/aux_/disable_warnings_push.hpp" + +#if BOOST_VERSION < 106100 +#include +namespace libtorrent { +using string_view = boost::string_ref; +} +#else +#include +namespace libtorrent { +using string_view = boost::string_view; +} +#endif + +#include "libtorrent/aux_/disable_warnings_pop.hpp" + +#endif + diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 8d2473ec7..ee07a9f95 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -67,7 +67,7 @@ namespace libtorrent // internal, exposed for the unit test TORRENT_EXTRA_EXPORT void sanitize_append_path_element(std::string& path - , char const* element, int element_len); + , string_view element); TORRENT_EXTRA_EXPORT bool verify_encoding(std::string& target); // the web_seed_entry holds information about a web seed (also known @@ -476,7 +476,7 @@ namespace libtorrent { return m_comment; } // dht nodes to add to the routing table/bootstrap from - typedef std::vector > nodes_t; + using nodes_t = std::vector>; // If this torrent contains any DHT nodes, they are put in this vector in // their original form (host name and port number). diff --git a/src/bdecode.cpp b/src/bdecode.cpp index cd11d273f..013c3ea62 100644 --- a/src/bdecode.cpp +++ b/src/bdecode.cpp @@ -109,22 +109,6 @@ namespace libtorrent // reading a key or a vale. 0 means key 1 is value std::uint32_t state:1; }; - - // str1 is 0-terminated - // str2 is not, str2 is len2 chars - bool string_equal(char const* str1, char const* str2, int len2) - { - while (len2 > 0) - { - if (*str1 != *str2) return false; - if (*str1 == 0) return false; - ++str1; - ++str2; - --len2; - } - return *str1 == 0; - } - } // anonymous namespace @@ -305,7 +289,7 @@ namespace libtorrent span bdecode_node::data_section() const { - if (m_token_idx == -1) return span(); + if (m_token_idx == -1) return {}; TORRENT_ASSERT(m_token_idx != -1); bdecode_token const& t = m_root_tokens[m_token_idx]; @@ -347,8 +331,8 @@ namespace libtorrent return bdecode_node(tokens, m_buffer, m_buffer_size, token); } - std::string bdecode_node::list_string_value_at(int i - , char const* default_val) + string_view bdecode_node::list_string_value_at(int i + , string_view default_val) { bdecode_node n = list_at(i); if (n.type() != bdecode_node::string_t) return default_val; @@ -394,7 +378,7 @@ namespace libtorrent return ret; } - std::pair bdecode_node::dict_at(int i) const + std::pair bdecode_node::dict_at(int i) const { TORRENT_ASSERT(type() == dict_t); TORRENT_ASSERT(m_token_idx != -1); @@ -482,7 +466,7 @@ namespace libtorrent return ret; } - bdecode_node bdecode_node::dict_find(std::string key) const + bdecode_node bdecode_node::dict_find(string_view key) const { TORRENT_ASSERT(type() == dict_t); @@ -495,9 +479,9 @@ namespace libtorrent { bdecode_token const& t = tokens[token]; TORRENT_ASSERT(t.type == bdecode_token::string); - int size = m_root_tokens[token + 1].offset - t.offset - t.start_offset(); + int const size = m_root_tokens[token + 1].offset - t.offset - t.start_offset(); if (int(key.size()) == size - && std::equal(key.c_str(), key.c_str() + size, m_buffer + && std::equal(key.data(), key.data() + size, m_buffer + t.offset + t.start_offset())) { // skip key @@ -518,7 +502,7 @@ namespace libtorrent return bdecode_node(); } - bdecode_node bdecode_node::dict_find_list(char const* key) const + bdecode_node bdecode_node::dict_find_list(string_view key) const { bdecode_node ret = dict_find(key); if (ret.type() == bdecode_node::list_t) @@ -526,7 +510,7 @@ namespace libtorrent return bdecode_node(); } - bdecode_node bdecode_node::dict_find_dict(std::string key) const + bdecode_node bdecode_node::dict_find_dict(string_view key) const { bdecode_node ret = dict_find(key); if (ret.type() == bdecode_node::dict_t) @@ -534,15 +518,7 @@ namespace libtorrent return bdecode_node(); } - bdecode_node bdecode_node::dict_find_dict(char const* key) const - { - bdecode_node ret = dict_find(key); - if (ret.type() == bdecode_node::dict_t) - return ret; - return bdecode_node(); - } - - bdecode_node bdecode_node::dict_find_string(char const* key) const + bdecode_node bdecode_node::dict_find_string(string_view key) const { bdecode_node ret = dict_find(key); if (ret.type() == bdecode_node::string_t) @@ -550,7 +526,7 @@ namespace libtorrent return bdecode_node(); } - bdecode_node bdecode_node::dict_find_int(char const* key) const + bdecode_node bdecode_node::dict_find_int(string_view key) const { bdecode_node ret = dict_find(key); if (ret.type() == bdecode_node::int_t) @@ -558,50 +534,15 @@ namespace libtorrent return bdecode_node(); } - - bdecode_node bdecode_node::dict_find(char const* key) const - { - TORRENT_ASSERT(type() == dict_t); - - bdecode_token const* tokens = m_root_tokens; - - // this is the first item - int token = m_token_idx + 1; - - while (tokens[token].type != bdecode_token::end) - { - bdecode_token const& t = tokens[token]; - TORRENT_ASSERT(t.type == bdecode_token::string); - int size = m_root_tokens[token + 1].offset - t.offset - t.start_offset(); - if (string_equal(key, m_buffer + t.offset + t.start_offset(), size)) - { - // skip key - token += t.next_item; - TORRENT_ASSERT(tokens[token].type != bdecode_token::end); - - return bdecode_node(tokens, m_buffer, m_buffer_size, token); - } - - // skip key - token += t.next_item; - TORRENT_ASSERT(tokens[token].type != bdecode_token::end); - - // skip value - token += tokens[token].next_item; - } - - return bdecode_node(); - } - - std::string bdecode_node::dict_find_string_value(char const* key - , char const* default_value) const + string_view bdecode_node::dict_find_string_value(string_view key + , string_view default_value) const { bdecode_node n = dict_find(key); if (n.type() != bdecode_node::string_t) return default_value; return n.string_value(); } - std::int64_t bdecode_node::dict_find_int_value(char const* key + std::int64_t bdecode_node::dict_find_int_value(string_view key , std::int64_t default_val) const { bdecode_node n = dict_find(key); @@ -629,14 +570,14 @@ namespace libtorrent return val; } - std::string bdecode_node::string_value() const + string_view bdecode_node::string_value() const { TORRENT_ASSERT(type() == string_t); bdecode_token const& t = m_root_tokens[m_token_idx]; - int size = m_root_tokens[m_token_idx + 1].offset - t.offset - t.start_offset(); + size_t const size = m_root_tokens[m_token_idx + 1].offset - t.offset - t.start_offset(); TORRENT_ASSERT(t.type == bdecode_token::string); - return std::string(m_buffer + t.offset + t.start_offset(), size); + return string_view(m_buffer + t.offset + t.start_offset(), size); } char const* bdecode_node::string_ptr() const @@ -982,12 +923,13 @@ done: } } - void print_string(std::string& ret, char const* str, int len, bool single_line) + void print_string(std::string& ret, string_view str, bool single_line) { + int const len = int(str.size()); bool printable = true; for (int i = 0; i < len; ++i) { - char c = str[i]; + char const c = str[i]; if (c >= 32 && c < 127) continue; printable = false; break; @@ -997,24 +939,24 @@ done: { if (single_line && len > 30) { - ret.append(str, 14); + ret.append(str.data(), 14); ret += "..."; - ret.append(str + len-14, 14); + ret.append(str.data() + len-14, 14); } else - ret.append(str, len); + ret.append(str.data(), len); ret += "'"; return; } if (single_line && len > 20) { - escape_string(ret, str, 9); + escape_string(ret, str.data(), 9); ret += "..."; - escape_string(ret, str + len - 9, 9); + escape_string(ret, str.data() + len - 9, 9); } else { - escape_string(ret, str, len); + escape_string(ret, str.data(), len); } ret += "'"; } @@ -1043,7 +985,7 @@ done: } case bdecode_node::string_t: { - print_string(ret, e.string_ptr(), e.string_length(), single_line); + print_string(ret, e.string_value(), single_line); return ret; } case bdecode_node::list_t: @@ -1071,8 +1013,8 @@ done: for (int i = 0; i < e.dict_size(); ++i) { if (i == 0 && one_liner) ret += " "; - std::pair ent = e.dict_at(i); - print_string(ret, ent.first.c_str(), int(ent.first.size()), true); + std::pair ent = e.dict_at(i); + print_string(ret, ent.first, true); ret += ": "; ret += print_entry(ent.second, single_line, indent + 2); if (i < e.dict_size() - 1) ret += (one_liner?", ":indent_str); diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 93ae0f336..c5aa378da 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1799,8 +1799,8 @@ namespace libtorrent int last_seen_complete = std::uint8_t(root.dict_find_int_value("complete_ago", -1)); if (last_seen_complete >= 0) set_last_seen_complete(last_seen_complete); - std::string client_info = root.dict_find_string_value("v"); - if (!client_info.empty()) m_client_version = client_info; + auto client_info = root.dict_find_string_value("v"); + if (!client_info.empty()) m_client_version = client_info.to_string(); int reqq = int(root.dict_find_int_value("reqq")); if (reqq > 0) max_out_request_queue(reqq); @@ -1812,7 +1812,7 @@ namespace libtorrent && root.dict_find_int_value("share_mode", 0)) set_share_mode(true); - std::string myip = root.dict_find_string_value("yourip"); + auto myip = root.dict_find_string_value("yourip"); if (!myip.empty()) { if (myip.size() == address_v4::bytes_type().size()) diff --git a/src/entry.cpp b/src/entry.cpp index d62082c7b..ee818caf4 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -373,7 +373,7 @@ namespace libtorrent switch (e.type()) { case bdecode_node::string_t: - this->string() = e.string_value(); + this->string() = e.string_value().to_string(); break; case bdecode_node::int_t: this->integer() = e.int_value(); @@ -383,8 +383,8 @@ namespace libtorrent dictionary_type& d = this->dict(); for (int i = 0; i < e.dict_size(); ++i) { - std::pair elem = e.dict_at(i); - d[elem.first] = elem.second; + std::pair elem = e.dict_at(i); + d[elem.first.to_string()] = elem.second; } break; } diff --git a/src/file.cpp b/src/file.cpp index 25be33a14..f8e834f4a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -624,10 +624,10 @@ namespace libtorrent ec.assign(errno, system_category()); copyfile_state_free(state); #else - std::string f1 = convert_to_native(inf); - std::string f2 = convert_to_native(newf); + std::string const f1 = convert_to_native(inf); + std::string const f2 = convert_to_native(newf); - int infd = ::open(f1.c_str(), O_RDONLY); + int const infd = ::open(f1.c_str(), O_RDONLY); if (infd < 0) { ec.assign(errno, system_category()); @@ -636,11 +636,11 @@ namespace libtorrent // rely on default umask to filter x and w permissions // for group and others - int permissions = S_IRUSR | S_IWUSR + int const permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - int outfd = ::open(f2.c_str(), O_WRONLY | O_CREAT, permissions); + int const outfd = ::open(f2.c_str(), O_WRONLY | O_CREAT, permissions); if (outfd < 0) { close(infd); @@ -650,14 +650,14 @@ namespace libtorrent char buffer[4096]; for (;;) { - int num_read = read(infd, buffer, sizeof(buffer)); + int const num_read = read(infd, buffer, sizeof(buffer)); if (num_read == 0) break; if (num_read < 0) { ec.assign(errno, system_category()); break; } - int num_written = write(outfd, buffer, num_read); + int const num_written = write(outfd, buffer, num_read); if (num_written < num_read) { ec.assign(errno, system_category()); @@ -908,21 +908,15 @@ namespace libtorrent return std::string(sep + 1); } - void append_path(std::string& branch, std::string const& leaf) + void append_path(std::string& branch, string_view leaf) { - append_path(branch, leaf.c_str(), int(leaf.size())); - } - - void append_path(std::string& branch - , char const* str, int len) - { - TORRENT_ASSERT(!is_complete(std::string(str, len))); + TORRENT_ASSERT(!is_complete(leaf)); if (branch.empty() || branch == ".") { - branch.assign(str, len); + branch.assign(leaf.data(), leaf.size()); return; } - if (len == 0) return; + if (leaf.size() == 0) return; #if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2) #define TORRENT_SEPARATOR_CHAR '\\' @@ -934,14 +928,14 @@ namespace libtorrent #endif if (need_sep) branch += TORRENT_SEPARATOR_CHAR; - branch.append(str, len); + branch.append(leaf.data(), leaf.size()); } - std::string combine_path(std::string const& lhs, std::string const& rhs) + std::string combine_path(string_view lhs, string_view rhs) { TORRENT_ASSERT(!is_complete(rhs)); - if (lhs.empty() || lhs == ".") return rhs; - if (rhs.empty() || rhs == ".") return lhs; + if (lhs.empty() || lhs == ".") return rhs.to_string(); + if (rhs.empty() || rhs == ".") return lhs.to_string(); #if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2) #define TORRENT_SEPARATOR "\\" @@ -953,8 +947,10 @@ namespace libtorrent std::string ret; int target_size = int(lhs.size() + rhs.size() + 2); ret.resize(target_size); - target_size = std::snprintf(&ret[0], target_size, "%s%s%s", lhs.c_str() - , (need_sep?TORRENT_SEPARATOR:""), rhs.c_str()); + target_size = std::snprintf(&ret[0], target_size, "%*s%s%*s" + , int(lhs.size()), lhs.data() + , (need_sep?TORRENT_SEPARATOR:"") + , int(rhs.size()), rhs.data()); ret.resize(target_size); return ret; } @@ -981,20 +977,20 @@ namespace libtorrent } #if TORRENT_USE_UNC_PATHS - std::string canonicalize_path(std::string const& f) + std::string canonicalize_path(string_view f) { std::string ret; ret.resize(f.size()); char* write_cur = &ret[0]; char* last_write_sep = write_cur; - char const* read_cur = f.c_str(); + char const* read_cur = f.data(); char const* last_read_sep = read_cur; // the last_*_sep pointers point to one past // the last path separator encountered and is - // initializes to the first character in the path - while (*read_cur) + // initialized to the first character in the path + for (int i = 0; i < int(f.size()); ++i) { if (*read_cur != '\\') { @@ -1135,14 +1131,14 @@ namespace libtorrent remove(f, ec); } - std::string complete(std::string const& f) + std::string complete(string_view f) { - if (is_complete(f)) return f; + if (is_complete(f)) return f.to_string(); if (f == ".") return current_working_directory(); return combine_path(current_working_directory(), f); } - bool is_complete(std::string const& f) + bool is_complete(string_view f) { if (f.empty()) return false; #if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2) diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 9f73800ce..796cf65f6 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -198,6 +198,20 @@ namespace libtorrent file_entry::~file_entry() = default; #endif // TORRENT_NO_DEPRECATE + internal_file_entry::internal_file_entry() + : offset(0) + , symlink_index(not_a_symlink) + , no_root_dir(false) + , size(0) + , name_len(name_is_owned) + , pad_file(false) + , hidden_attribute(false) + , executable_attribute(false) + , symlink_attribute(false) + , name(nullptr) + , path_index(-1) + {} + internal_file_entry::~internal_file_entry() { if (name_len == name_is_owned) free(const_cast(name)); @@ -233,14 +247,53 @@ namespace libtorrent executable_attribute = fe.executable_attribute; symlink_attribute = fe.symlink_attribute; no_root_dir = fe.no_root_dir; - set_name(fe.filename().c_str()); + set_name(fe.filename().to_string().c_str()); return *this; } + internal_file_entry::internal_file_entry(internal_file_entry&& fe) + : offset(fe.offset) + , symlink_index(fe.symlink_index) + , no_root_dir(fe.no_root_dir) + , size(fe.size) + , name_len(fe.name_len) + , pad_file(fe.pad_file) + , hidden_attribute(fe.hidden_attribute) + , executable_attribute(fe.executable_attribute) + , symlink_attribute(fe.symlink_attribute) + , name(fe.name) + , path_index(fe.path_index) + { + fe.name_len = name_is_owned; + fe.name = nullptr; + } + + internal_file_entry& internal_file_entry::operator=(internal_file_entry&& fe) + { + offset = fe.offset; + size = fe.size; + path_index = fe.path_index; + symlink_index = fe.symlink_index; + pad_file = fe.pad_file; + hidden_attribute = fe.hidden_attribute; + executable_attribute = fe.executable_attribute; + symlink_attribute = fe.symlink_attribute; + no_root_dir = fe.no_root_dir; + name = fe.name; + name_len = fe.name_len; + + fe.name_len = name_is_owned; + fe.name = nullptr; + return *this; + } + + file_storage::file_storage(file_storage&&) = default; + file_storage& file_storage::operator=(file_storage&&) = default; + // if borrow_chars >= 0, don't take ownership over n, just // point to it. It points to borrow_chars number of characters. // if borrow_chars == -1, n is a 0-terminated string that - // should be copied + // should be copied. void internal_file_entry::set_name(char const* n, bool borrow_string, int string_len) { TORRENT_ASSERT(string_len >= 0); @@ -268,10 +321,10 @@ namespace libtorrent } } - std::string internal_file_entry::filename() const + string_view internal_file_entry::filename() const { - if (name_len != name_is_owned) return std::string(name, name_len); - return name ? name : ""; + if (name_len != name_is_owned) return { name, size_t(name_len) }; + return name ? string_view(name) : string_view(); } void file_storage::apply_pointer_offset(ptrdiff_t off) @@ -320,7 +373,7 @@ namespace libtorrent } void file_storage::add_file(std::wstring const& file, std::int64_t file_size - , int file_flags, std::time_t mtime, std::string const& symlink_path) + , int file_flags, std::time_t mtime, string_view symlink_path) { std::string utf8; wchar_utf8(file, utf8); @@ -502,7 +555,7 @@ namespace libtorrent } void file_storage::add_file(std::string const& path, std::int64_t file_size - , int file_flags, std::time_t mtime, std::string const& symlink_path) + , int file_flags, std::time_t mtime, string_view symlink_path) { add_file_borrow(nullptr, 0, path, file_size, file_flags, nullptr, mtime , symlink_path); @@ -511,7 +564,7 @@ namespace libtorrent void file_storage::add_file_borrow(char const* filename, int filename_len , std::string const& path, std::int64_t file_size , std::uint32_t file_flags, char const* filehash - , std::int64_t mtime, std::string const& symlink_path) + , std::int64_t mtime, string_view symlink_path) { TORRENT_ASSERT_PRECOND(file_size >= 0); if (!has_parent_path(path)) @@ -560,7 +613,7 @@ namespace libtorrent && m_symlinks.size() < internal_file_entry::not_a_symlink - 1) { e.symlink_index = m_symlinks.size(); - m_symlinks.push_back(symlink_path); + m_symlinks.emplace_back(symlink_path.to_string()); } else { @@ -581,7 +634,7 @@ namespace libtorrent if (index >= int(m_file_hashes.size())) return sha1_hash(nullptr); return sha1_hash(m_file_hashes[index]); } - + std::string const& file_storage::symlink(int index) const { TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); @@ -599,10 +652,10 @@ namespace libtorrent namespace { template - void process_string_lowercase(CRC& crc, char const* str, int len) + void process_string_lowercase(CRC& crc, string_view str) { - for (int i = 0; i < len; ++i, ++str) - crc.process_byte(to_lower(*str)); + for (char const c : str) + crc.process_byte(to_lower(c)); } template @@ -629,7 +682,7 @@ namespace libtorrent if (!m_name.empty()) { - process_string_lowercase(crc, m_name.c_str(), int(m_name.size())); + process_string_lowercase(crc, m_name); TORRENT_ASSERT(m_name[m_name.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } @@ -652,45 +705,45 @@ namespace libtorrent if (fe.path_index == -2) { // -2 means this is an absolute path filename - process_string_lowercase(crc, fe.filename_ptr(), fe.filename_len()); + process_string_lowercase(crc, fe.filename()); } else if (fe.path_index == -1) { // -1 means no path if (!save_path.empty()) { - process_string_lowercase(crc, save_path.c_str(), int(save_path.size())); + process_string_lowercase(crc, save_path); TORRENT_ASSERT(save_path[save_path.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } - process_string_lowercase(crc, fe.filename_ptr(), fe.filename_len()); + process_string_lowercase(crc, fe.filename()); } else if (fe.no_root_dir) { if (!save_path.empty()) { - process_string_lowercase(crc, save_path.c_str(), int(save_path.size())); + process_string_lowercase(crc, save_path); TORRENT_ASSERT(save_path[save_path.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } std::string const& p = m_paths[fe.path_index]; if (!p.empty()) { - process_string_lowercase(crc, p.c_str(), int(p.size())); + process_string_lowercase(crc, p); TORRENT_ASSERT(p[p.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } - process_string_lowercase(crc, fe.filename_ptr(), fe.filename_len()); + process_string_lowercase(crc, fe.filename()); } else { if (!save_path.empty()) { - process_string_lowercase(crc, save_path.c_str(), int(save_path.size())); + process_string_lowercase(crc, save_path); TORRENT_ASSERT(save_path[save_path.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } - process_string_lowercase(crc, m_name.c_str(), int(m_name.size())); + process_string_lowercase(crc, m_name); TORRENT_ASSERT(m_name.size() > 0); TORRENT_ASSERT(m_name[m_name.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); @@ -698,18 +751,18 @@ namespace libtorrent std::string const& p = m_paths[fe.path_index]; if (!p.empty()) { - process_string_lowercase(crc, p.c_str(), int(p.size())); + process_string_lowercase(crc, p); TORRENT_ASSERT(p.size() > 0); TORRENT_ASSERT(p[p.size()-1] != TORRENT_SEPARATOR); crc.process_byte(TORRENT_SEPARATOR); } - process_string_lowercase(crc, fe.filename_ptr(), fe.filename_len()); + process_string_lowercase(crc, fe.filename()); } return crc.checksum(); } - std::string file_storage::file_path(int index, std::string const& save_path) const + std::string file_storage::file_path(int const index, std::string const& save_path) const { TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); internal_file_entry const& fe = m_files[index]; @@ -719,40 +772,40 @@ namespace libtorrent // -2 means this is an absolute path filename if (fe.path_index == -2) { - ret.assign(fe.filename_ptr(), fe.filename_len()); + ret = fe.filename().to_string(); } else if (fe.path_index == -1) { // -1 means no path - ret.reserve(save_path.size() + fe.filename_len() + 1); + ret.reserve(save_path.size() + fe.filename().size() + 1); ret.assign(save_path); - append_path(ret, fe.filename_ptr(), fe.filename_len()); + append_path(ret, fe.filename()); } else if (fe.no_root_dir) { std::string const& p = m_paths[fe.path_index]; - ret.reserve(save_path.size() + p.size() + fe.filename_len() + 2); + ret.reserve(save_path.size() + p.size() + fe.filename().size() + 2); ret.assign(save_path); append_path(ret, p); - append_path(ret, fe.filename_ptr(), fe.filename_len()); + append_path(ret, fe.filename()); } else { std::string const& p = m_paths[fe.path_index]; - ret.reserve(save_path.size() + m_name.size() + p.size() + fe.filename_len() + 3); + ret.reserve(save_path.size() + m_name.size() + p.size() + fe.filename().size() + 3); ret.assign(save_path); append_path(ret, m_name); append_path(ret, p); - append_path(ret, fe.filename_ptr(), fe.filename_len()); + append_path(ret, fe.filename()); } // a single return statement, just to make NRVO more likely to kick in return ret; } - std::string file_storage::file_name(int index) const + string_view file_storage::file_name(int index) const { TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); internal_file_entry const& fe = m_files[index]; @@ -857,13 +910,13 @@ namespace libtorrent std::string file_storage::file_path(internal_file_entry const& fe , std::string const& save_path) const { - int index = &fe - &m_files[0]; + int const index = &fe - &m_files[0]; return file_path(index, save_path); } std::string file_storage::file_name(internal_file_entry const& fe) const { - return fe.filename(); + return fe.filename().to_string(); } std::int64_t file_storage::file_size(internal_file_entry const& fe) const diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index a0eb778eb..881173c98 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -404,7 +404,7 @@ namespace libtorrent ec.assign(errors::invalid_tracker_response, get_libtorrent_category()); return false; } - ret.hostname = i.string_value(); + ret.hostname = i.string_value().to_string(); // extract port i = info.dict_find_int("port"); @@ -444,20 +444,20 @@ namespace libtorrent bdecode_node tracker_id = e.dict_find_string("tracker id"); if (tracker_id) - resp.trackerid = tracker_id.string_value(); + resp.trackerid = tracker_id.string_value().to_string(); // parse the response bdecode_node failure = e.dict_find_string("failure reason"); if (failure) { - resp.failure_reason = failure.string_value(); + resp.failure_reason = failure.string_value().to_string(); ec.assign(errors::tracker_failure, get_libtorrent_category()); return resp; } bdecode_node warning = e.dict_find_string("warning message"); if (warning) - resp.warning_message = warning.string_value(); + resp.warning_message = warning.string_value().to_string(); if (0 != (flags & tracker_request::scrape_request)) { diff --git a/src/kademlia/find_data.cpp b/src/kademlia/find_data.cpp index 1718db604..652e127a5 100644 --- a/src/kademlia/find_data.cpp +++ b/src/kademlia/find_data.cpp @@ -73,7 +73,7 @@ void find_data_observer::reply(msg const& m) if (token) { static_cast(algorithm())->got_write_token( - node_id(id.string_ptr()), token.string_value()); + node_id(id.string_ptr()), token.string_value().to_string()); } traversal_observer::reply(m); @@ -109,7 +109,7 @@ void find_data::start() traversal_algorithm::start(); } -void find_data::got_write_token(node_id const& n, std::string const& write_token) +void find_data::got_write_token(node_id const& n, std::string write_token) { #ifndef TORRENT_DISABLE_LOGGING get_node().observer()->log(dht_logger::traversal @@ -117,7 +117,7 @@ void find_data::got_write_token(node_id const& n, std::string const& write_token , static_cast(this), aux::to_hex(write_token).c_str() , aux::to_hex(n).c_str()); #endif - m_write_tokens[n] = write_token; + m_write_tokens[n] = std::move(write_token); } observer_ptr find_data::new_observer(void* ptr diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 8623dbf45..4e0d879df 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -146,7 +146,7 @@ void node::update_node_id() m_rpc.update_node_id(m_id); } -bool node::verify_token(std::string const& token, sha1_hash const& info_hash +bool node::verify_token(string_view token, sha1_hash const& info_hash , udp::endpoint const& addr) const { if (token.length() != 4) @@ -337,7 +337,7 @@ void node::incoming(msg const& m) { m_observer->log(dht_logger::node, "INCOMING ERROR: (%" PRId64 ") %s" , err.list_int_value_at(0) - , err.list_string_value_at(1).c_str()); + , err.list_string_value_at(1).to_string().c_str()); } else { @@ -795,7 +795,7 @@ void node::incoming_request(msg const& m, entry& e) { e = entry(entry::dictionary_t); e["y"] = "r"; - e["t"] = m.message.dict_find_string_value("t"); + e["t"] = m.message.dict_find_string_value("t").to_string(); key_desc_t top_desc[] = { {"q", bdecode_node::string_t, 0, 0}, @@ -961,10 +961,11 @@ void node::incoming_request(msg const& m, entry& e) m_table.node_seen(id, m.addr, 0xffff); tcp::endpoint addr = tcp::endpoint(m.addr.address(), port); - std::string name = msg_keys[3] ? msg_keys[3].string_value() : std::string(); + string_view name = msg_keys[3] ? msg_keys[3].string_value() : string_view(); bool seed = msg_keys[4] && msg_keys[4].int_value(); - m_storage.announce_peer(info_hash, addr, name, seed); + // TODO: 3 should we update the dht storage API to take a string_ref? + m_storage.announce_peer(info_hash, addr, name.to_string(), seed); } else if (query_len == 3 && memcmp(query, "put", 3) == 0) { @@ -1198,10 +1199,8 @@ void node::write_nodes_entries(sha1_hash const& info_hash bdecode_node wanted = want.list_at(i); if (wanted.type() != bdecode_node::string_t) continue; - std::map::const_iterator wanted_node - = m_nodes.find(wanted.string_value()); - if (wanted_node == m_nodes.end()) - continue; + auto wanted_node = m_nodes.find(wanted.string_value().to_string()); + if (wanted_node == m_nodes.end()) continue; nodes_t n; wanted_node->second->m_table.find_node(info_hash, n, 0); write_nodes_entry(r[wanted_node->second->protocol_nodes_key()], n); diff --git a/src/kademlia/rpc_manager.cpp b/src/kademlia/rpc_manager.cpp index e939121a5..1a8806ead 100644 --- a/src/kademlia/rpc_manager.cpp +++ b/src/kademlia/rpc_manager.cpp @@ -270,10 +270,10 @@ bool rpc_manager::incoming(msg const& m, node_id* id) // if we don't have the transaction id in our // request list, ignore the packet - std::string transaction_id = m.message.dict_find_string_value("t"); + auto transaction_id = m.message.dict_find_string_value("t"); if (transaction_id.empty()) return false; - std::string::const_iterator ptr = transaction_id.begin(); + auto ptr = transaction_id.begin(); int tid = transaction_id.size() != 2 ? -1 : io::read_uint16(ptr); observer_ptr o; @@ -325,7 +325,7 @@ bool rpc_manager::incoming(msg const& m, node_id* id) m_log->log(dht_logger::rpc_manager, "reply with error from %s: (%" PRId64 ") %s" , print_endpoint(m.addr).c_str() , err.list_int_value_at(0) - , err.list_string_value_at(1).c_str()); + , err.list_string_value_at(1).to_string().c_str()); } else { diff --git a/src/magnet_uri.cpp b/src/magnet_uri.cpp index e0e5c186f..3f4345b48 100644 --- a/src/magnet_uri.cpp +++ b/src/magnet_uri.cpp @@ -159,7 +159,7 @@ namespace libtorrent if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle(); if (btih.size() == 40 + 9) aux::from_hex({&btih[9], 40}, params.info_hash.data()); - else params.info_hash.assign(base32decode(btih.substr(9))); + else params.info_hash.assign(base32decode(btih.substr(9)).c_str()); return ses.add_torrent(params); } @@ -175,6 +175,7 @@ namespace libtorrent #endif // BOOST_NO_EXCEPTIONS #endif // TORRENT_NO_DEPRECATE + // TODO: 3 take string_ref here instead void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); diff --git a/src/read_resume_data.cpp b/src/read_resume_data.cpp index cec5fbf28..24b3cbcbc 100644 --- a/src/read_resume_data.cpp +++ b/src/read_resume_data.cpp @@ -70,7 +70,8 @@ namespace libtorrent if (bdecode_node alloc = rd.dict_find_string("allocation")) { ret.storage_mode = (alloc.string_value() == "allocate" - || alloc.string_value() == "full") ? storage_mode_allocate : storage_mode_sparse; + || alloc.string_value() == "full") + ? storage_mode_allocate : storage_mode_sparse; } if (rd.dict_find_string_value("file-format") @@ -80,16 +81,16 @@ namespace libtorrent return ret; } - std::string info_hash = rd.dict_find_string_value("info-hash"); + auto info_hash = rd.dict_find_string_value("info-hash"); if (info_hash.size() != 20) { ec = error_code(errors::missing_info_hash, get_libtorrent_category()); return ret; } - ret.name = rd.dict_find_string_value("name"); + ret.name = rd.dict_find_string_value("name").to_string(); - ret.info_hash.assign(info_hash); + ret.info_hash.assign(info_hash.data()); // TODO: 4 add unit test for this, and all other fields of the resume data bdecode_node info = rd.dict_find_dict("info"); @@ -141,12 +142,12 @@ namespace libtorrent apply_flag(ret.flags, rd, "sequential_download", add_torrent_params::flag_sequential_download); apply_flag(ret.flags, rd, "paused", add_torrent_params::flag_paused); - ret.save_path = rd.dict_find_string_value("save_path"); + ret.save_path = rd.dict_find_string_value("save_path").to_string(); - ret.url = rd.dict_find_string_value("url"); + ret.url = rd.dict_find_string_value("url").to_string(); #ifndef TORRENT_NO_DEPRECATE // deprecated in 1.2 - ret.uuid = rd.dict_find_string_value("uuid"); + ret.uuid = rd.dict_find_string_value("uuid").to_string(); #endif bdecode_node mapped_files = rd.dict_find_list("mapped_files"); @@ -154,9 +155,9 @@ namespace libtorrent { for (int i = 0; i < mapped_files.list_size(); ++i) { - std::string new_filename = mapped_files.list_string_value_at(i); + auto new_filename = mapped_files.list_string_value_at(i); if (new_filename.empty()) continue; - ret.renamed_files[i] = new_filename; + ret.renamed_files[i] = new_filename.to_string(); } } @@ -199,7 +200,7 @@ namespace libtorrent for (int j = 0; j < tier_list.list_size(); ++j) { - ret.trackers.push_back(tier_list.list_string_value_at(j)); + ret.trackers.push_back(tier_list.list_string_value_at(j).to_string()); ret.tracker_tiers.push_back(tier); } ++tier; @@ -223,9 +224,9 @@ namespace libtorrent { for (int i = 0; i < url_list.list_size(); ++i) { - std::string url = url_list.list_string_value_at(i); + auto url = url_list.list_string_value_at(i); if (url.empty()) continue; - ret.url_seeds.push_back(url); + ret.url_seeds.push_back(url.to_string()); } } @@ -233,9 +234,9 @@ namespace libtorrent { for (int i = 0; i < httpseeds.list_size(); ++i) { - std::string url = httpseeds.list_string_value_at(i); + auto url = httpseeds.list_string_value_at(i); if (url.empty()) continue; - ret.http_seeds.push_back(url); + ret.http_seeds.push_back(url.to_string()); } } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index aa651288a..82c609ac9 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -711,11 +711,11 @@ namespace aux { val = settings.dict_find_int("proxy_peer_connections"); if (val) m_settings.set_bool(settings_pack::proxy_peer_connections, val.int_value() != 0); val = settings.dict_find_string("hostname"); - if (val) m_settings.set_str(settings_pack::proxy_hostname, val.string_value()); + if (val) m_settings.set_str(settings_pack::proxy_hostname, val.string_value().to_string()); val = settings.dict_find_string("password"); - if (val) m_settings.set_str(settings_pack::proxy_password, val.string_value()); + if (val) m_settings.set_str(settings_pack::proxy_password, val.string_value().to_string()); val = settings.dict_find_string("username"); - if (val) m_settings.set_str(settings_pack::proxy_username, val.string_value()); + if (val) m_settings.set_str(settings_pack::proxy_username, val.string_value().to_string()); need_update_proxy = true; } } diff --git a/src/settings_pack.cpp b/src/settings_pack.cpp index 185b20839..f5370d754 100644 --- a/src/settings_pack.cpp +++ b/src/settings_pack.cpp @@ -48,13 +48,11 @@ namespace { } template - void insort_replace(std::vector >& c, std::pair const& v) + void insort_replace(std::vector>& c, std::pair v) { - typedef std::vector > container_t; - typename container_t::iterator i = std::lower_bound(c.begin(), c.end(), v - , &compare_first); - if (i != c.end() && i->first == v.first) i->second = v.second; - else c.insert(i, v); + auto i = std::lower_bound(c.begin(), c.end(), v, &compare_first); + if (i != c.end() && i->first == v.first) i->second = std::move(v.second); + else c.emplace(i, std::move(v)); } } @@ -395,7 +393,7 @@ namespace libtorrent for (int i = 0; i < settings.dict_size(); ++i) { - std::string key; + string_view key; bdecode_node val; std::tie(key, val) = settings.dict_at(i); switch (val.type()) @@ -426,7 +424,7 @@ namespace libtorrent for (int k = 0; k < sizeof(str_settings)/sizeof(str_settings[0]); ++k) { if (key != str_settings[k].name) continue; - pack->set_str(settings_pack::string_type_base + k, val.string_value()); + pack->set_str(settings_pack::string_type_base + k, val.string_value().to_string()); break; } break; @@ -473,7 +471,7 @@ namespace libtorrent { if (str_settings[i].offset == 0) continue; std::string& val = *(std::string*)(((char*)&s) + str_settings[i].offset); - int setting_name = settings_pack::string_type_base + i; + int const setting_name = settings_pack::string_type_base + i; if (val == current.get_str(setting_name)) continue; p->set_str(setting_name, val); } @@ -482,7 +480,7 @@ namespace libtorrent { if (int_settings[i].offset == 0) continue; int& val = *(int*)(((char*)&s) + int_settings[i].offset); - int setting_name = settings_pack::int_type_base + i; + int const setting_name = settings_pack::int_type_base + i; if (val == current.get_int(setting_name)) continue; p->set_int(setting_name, val); } @@ -491,7 +489,7 @@ namespace libtorrent { if (bool_settings[i].offset == 0) continue; bool& val = *(bool*)(((char*)&s) + bool_settings[i].offset); - int setting_name = settings_pack::bool_type_base + i; + int const setting_name = settings_pack::bool_type_base + i; if (val == current.get_bool(setting_name)) continue; p->set_bool(setting_name, val); } @@ -648,15 +646,15 @@ namespace libtorrent } } - void settings_pack::set_str(int name, std::string val) + void settings_pack::set_str(int const name, std::string val) { TORRENT_ASSERT((name & type_mask) == string_type_base); if ((name & type_mask) != string_type_base) return; - std::pair v(name, val); - insort_replace(m_strings, v); + std::pair v(name, std::move(val)); + insort_replace(m_strings, std::move(v)); } - void settings_pack::set_int(int name, int val) + void settings_pack::set_int(int const name, int const val) { TORRENT_ASSERT((name & type_mask) == int_type_base); if ((name & type_mask) != int_type_base) return; @@ -664,7 +662,7 @@ namespace libtorrent insort_replace(m_ints, v); } - void settings_pack::set_bool(int name, bool val) + void settings_pack::set_bool(int const name, bool const val) { TORRENT_ASSERT((name & type_mask) == bool_type_base); if ((name & type_mask) != bool_type_base) return; @@ -672,7 +670,7 @@ namespace libtorrent insort_replace(m_bools, v); } - bool settings_pack::has_val(int name) const + bool settings_pack::has_val(int const name) const { switch (name & type_mask) { @@ -683,8 +681,7 @@ namespace libtorrent if (m_strings.size() == settings_pack::num_string_settings) return true; std::pair v(name, std::string()); - std::vector >::const_iterator i = - std::lower_bound(m_strings.begin(), m_strings.end(), v + auto i = std::lower_bound(m_strings.begin(), m_strings.end(), v , &compare_first); return i != m_strings.end() && i->first == name; } @@ -695,8 +692,7 @@ namespace libtorrent if (m_ints.size() == settings_pack::num_int_settings) return true; std::pair v(name, 0); - std::vector >::const_iterator i = - std::lower_bound(m_ints.begin(), m_ints.end(), v + auto i = std::lower_bound(m_ints.begin(), m_ints.end(), v , &compare_first); return i != m_ints.end() && i->first == name; } @@ -707,8 +703,7 @@ namespace libtorrent if (m_bools.size() == settings_pack::num_bool_settings) return true; std::pair v(name, false); - std::vector >::const_iterator i = - std::lower_bound(m_bools.begin(), m_bools.end(), v + auto i = std::lower_bound(m_bools.begin(), m_bools.end(), v , &compare_first); return i != m_bools.end() && i->first == name; } @@ -717,10 +712,11 @@ namespace libtorrent return false; } - std::string settings_pack::get_str(int name) const + std::string const& settings_pack::get_str(int name) const { + static std::string const empty; TORRENT_ASSERT((name & type_mask) == string_type_base); - if ((name & type_mask) != string_type_base) return std::string(); + if ((name & type_mask) != string_type_base) return empty; // 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 @@ -730,11 +726,10 @@ namespace libtorrent return m_strings[name & index_mask].second; } std::pair v(name, std::string()); - std::vector >::const_iterator i - = std::lower_bound(m_strings.begin(), m_strings.end(), v + auto i = std::lower_bound(m_strings.begin(), m_strings.end(), v , &compare_first); if (i != m_strings.end() && i->first == name) return i->second; - return std::string(); + return empty; } int settings_pack::get_int(int name) const @@ -750,8 +745,7 @@ namespace libtorrent return m_ints[name & index_mask].second; } std::pair v(name, 0); - std::vector >::const_iterator i - = std::lower_bound(m_ints.begin(), m_ints.end(), v + auto i = std::lower_bound(m_ints.begin(), m_ints.end(), v , &compare_first); if (i != m_ints.end() && i->first == name) return i->second; return 0; @@ -770,8 +764,7 @@ namespace libtorrent return m_bools[name & index_mask].second; } std::pair v(name, false); - std::vector >::const_iterator i - = std::lower_bound(m_bools.begin(), m_bools.end(), v + auto i = std::lower_bound(m_bools.begin(), m_bools.end(), v , &compare_first); if (i != m_bools.end() && i->first == name) return i->second; return false; diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 2505c0a48..744d9d169 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -150,16 +150,16 @@ namespace libtorrent return valid_encoding; } - void sanitize_append_path_element(std::string& path, char const* element, int element_len) + void sanitize_append_path_element(std::string& path, string_view element) { - if (element_len == 1 && element[0] == '.') return; + if (element.size() == 1 && element[0] == '.') return; #ifdef TORRENT_WINDOWS #define TORRENT_SEPARATOR "\\" #else #define TORRENT_SEPARATOR "/" #endif - path.reserve(path.size() + element_len + 2); + path.reserve(path.size() + element.size() + 2); int added_separator = 0; if (!path.empty()) { @@ -167,7 +167,7 @@ namespace libtorrent added_separator = 1; } - if (element_len == 0) + if (element.empty()) { path += "_"; return; @@ -188,18 +188,17 @@ namespace libtorrent // this is not very efficient, but it only affects some specific // windows builds for now anyway (not even the default windows build) - std::string pe(element, element_len); + std::string pe = element.to_string(); char const* file_end = strrchr(pe.c_str(), '.'); - std::string name; - if (file_end) name.assign(pe.c_str(), file_end); - else name = pe; + std::string name = file_end + ? std::string(pe.data(), file_end) + : pe; std::transform(name.begin(), name.end(), name.begin(), &to_lower); char const* str = std::find(reserved_names, reserved_names + num_names, name); if (str != reserved + num_names) { pe = "_" + pe; - element = pe.c_str(); - element_len = pe.size(); + element = string_view(); } #endif // this counts the number of unicode characters @@ -211,7 +210,7 @@ namespace libtorrent // the number of dots we've added char num_dots = 0; bool found_extension = false; - for (int i = 0; i < element_len; ++i) + for (int i = 0; i < element.size(); ++i) { if (element[i] == '/' || element[i] == '\\' @@ -241,7 +240,7 @@ namespace libtorrent else if ((element[i] & 0xe0) == 0xc0) { // 2 bytes - if (element_len - i < 2 + if (element.size() - i < 2 || (element[i+1] & 0xc0) != 0x80) { path += '_'; @@ -264,7 +263,7 @@ namespace libtorrent else if ((element[i] & 0xf0) == 0xe0) { // 3 bytes - if (element_len - i < 3 + if (element.size() - i < 3 || (element[i+1] & 0xc0) != 0x80 || (element[i+2] & 0xc0) != 0x80 ) @@ -290,7 +289,7 @@ namespace libtorrent else if ((element[i] & 0xf8) == 0xf0) { // 4 bytes - if (element_len - i < 4 + if (element.size() - i < 4 || (element[i+1] & 0xc0) != 0x80 || (element[i+2] & 0xc0) != 0x80 || (element[i+3] & 0xc0) != 0x80 @@ -336,7 +335,8 @@ namespace libtorrent #endif { int dot = -1; - for (int j = element_len-1; j > (std::max)(element_len - 10, i); --j) + for (int j = int(element.size())-1; + j > (std::max)(int(element.size() - 10), i); --j) { if (element[j] != '.') continue; dot = j; @@ -417,7 +417,7 @@ namespace libtorrent filename = p.string_ptr() + info_ptr_diff; filename_len = p.string_length(); - sanitize_append_path_element(path, p.string_ptr(), p.string_length()); + sanitize_append_path_element(path, p.string_value()); } else { @@ -450,7 +450,7 @@ namespace libtorrent filename = e.string_ptr() + info_ptr_diff; filename_len = e.string_length(); } - sanitize_append_path_element(path, e.string_ptr(), e.string_length()); + sanitize_append_path_element(path, e.string_value()); } } @@ -486,8 +486,8 @@ namespace libtorrent { for (int i = 0, end(s_p.list_size()); i < end; ++i) { - std::string pe = s_p.list_at(i).string_value(); - symlink_path = combine_path(symlink_path, pe); + auto pe = s_p.list_at(i).string_value(); + append_path(symlink_path, pe); } } else @@ -1036,7 +1036,7 @@ namespace libtorrent if (ec) return ""; } if (m_info_dict.type() != bdecode_node::dict_t) return ""; - return m_info_dict.dict_find_string_value("ssl-cert"); + return m_info_dict.dict_find_string_value("ssl-cert").to_string(); } bool torrent_info::parse_info_section(bdecode_node const& info @@ -1090,8 +1090,7 @@ namespace libtorrent } std::string name; - sanitize_append_path_element(name, name_ent.string_ptr() - , name_ent.string_length()); + sanitize_append_path_element(name, name_ent.string_value()); if (name.empty()) name = aux::to_hex(m_info_hash); // extract file list @@ -1316,10 +1315,10 @@ namespace libtorrent bdecode_node link = torrent_file.dict_find_string("magnet-uri"); if (link) { - std::string uri = link.string_value(); + auto uri = link.string_value(); add_torrent_params p; - parse_magnet_uri(uri, p, ec); + parse_magnet_uri(uri.to_string(), p, ec); if (ec) return false; m_info_hash = p.info_hash; @@ -1379,7 +1378,7 @@ namespace libtorrent if (tier.type() != bdecode_node::list_t) continue; for (int k = 0, end2(tier.list_size()); k < end2; ++k) { - announce_entry e(tier.list_string_value_at(k)); + announce_entry e(tier.list_string_value_at(k).to_string()); e.trim(); if (e.url.empty()) continue; e.tier = j; @@ -1413,7 +1412,7 @@ namespace libtorrent if (m_urls.empty()) { - announce_entry e(torrent_file.dict_find_string_value("announce")); + announce_entry e(torrent_file.dict_find_string_value("announce").to_string()); e.fail_limit = 0; e.source = announce_entry::source_torrent; e.trim(); @@ -1435,7 +1434,7 @@ namespace libtorrent || n.list_at(1).type() != bdecode_node::int_t) continue; m_nodes.push_back(std::make_pair( - n.list_at(0).string_value() + n.list_at(0).string_value().to_string() , int(n.list_at(1).int_value()))); } } @@ -1452,7 +1451,7 @@ namespace libtorrent if (url_seeds && url_seeds.type() == bdecode_node::string_t && url_seeds.string_length() > 0) { - web_seed_entry ent(maybe_url_encode(url_seeds.string_value()) + web_seed_entry ent(maybe_url_encode(url_seeds.string_value().to_string()) , web_seed_entry::url_seed); if ((m_flags & multifile) && ent.url[ent.url.size()-1] != '/') ent.url += '/'; m_web_seeds.push_back(ent); @@ -1466,7 +1465,7 @@ namespace libtorrent bdecode_node url = url_seeds.list_at(i); if (url.type() != bdecode_node::string_t) continue; if (url.string_length() == 0) continue; - web_seed_entry ent(maybe_url_encode(url.string_value()) + web_seed_entry ent(maybe_url_encode(url.string_value().to_string()) , web_seed_entry::url_seed); if ((m_flags & multifile) && ent.url[ent.url.size()-1] != '/') ent.url += '/'; if (unique.count(ent.url)) continue; @@ -1480,7 +1479,7 @@ namespace libtorrent if (http_seeds && http_seeds.type() == bdecode_node::string_t && http_seeds.string_length() > 0) { - m_web_seeds.push_back(web_seed_entry(maybe_url_encode(http_seeds.string_value()) + m_web_seeds.push_back(web_seed_entry(maybe_url_encode(http_seeds.string_value().to_string()) , web_seed_entry::http_seed)); } else if (http_seeds && http_seeds.type() == bdecode_node::list_t) @@ -1491,19 +1490,19 @@ namespace libtorrent { bdecode_node url = http_seeds.list_at(i); if (url.type() != bdecode_node::string_t || url.string_length() == 0) continue; - std::string u = maybe_url_encode(url.string_value()); + std::string u = maybe_url_encode(url.string_value().to_string()); if (unique.count(u)) continue; unique.insert(u); m_web_seeds.push_back(web_seed_entry(u, web_seed_entry::http_seed)); } } - m_comment = torrent_file.dict_find_string_value("comment.utf-8"); - if (m_comment.empty()) m_comment = torrent_file.dict_find_string_value("comment"); + m_comment = torrent_file.dict_find_string_value("comment.utf-8").to_string(); + if (m_comment.empty()) m_comment = torrent_file.dict_find_string_value("comment").to_string(); verify_encoding(m_comment); - m_created_by = torrent_file.dict_find_string_value("created by.utf-8"); - if (m_created_by.empty()) m_created_by = torrent_file.dict_find_string_value("created by"); + m_created_by = torrent_file.dict_find_string_value("created by.utf-8").to_string(); + if (m_created_by.empty()) m_created_by = torrent_file.dict_find_string_value("created by").to_string(); verify_encoding(m_created_by); return true; diff --git a/test/test_bencoding.cpp b/test/test_bencoding.cpp index 3e7badf35..e97d35d35 100644 --- a/test/test_bencoding.cpp +++ b/test/test_bencoding.cpp @@ -226,7 +226,7 @@ TORRENT_TEST(lazy_entry) int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec); TEST_CHECK(ret == 0); TEST_CHECK(e.dict_size() == 1); - lazy_entry* d = e.dict_find(std::string("a\0b", 3)); + lazy_entry* d = e.dict_find({"a\0b", 3}); TEST_CHECK(d); TEST_EQUAL(d->type(), lazy_entry::int_t); TEST_EQUAL(d->int_value(), 1); diff --git a/test/test_dht.cpp b/test/test_dht.cpp index c39d5aabb..6eabebb2d 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -272,7 +272,7 @@ void send_dht_response(node& node, bdecode_node const& request, udp::endpoint co { entry e; e["y"] = "r"; - e["t"] = request.dict_find_string_value("t"); + e["t"] = request.dict_find_string_value("t").to_string(); // e["ip"] = endpoint_to_bytes(ep); e["r"] = args.a; e["r"].dict().insert(std::make_pair("id", generate_next().to_string())); @@ -342,7 +342,7 @@ void announce_immutable_items(node& node, udp::endpoint const* eps if (ret) { TEST_EQUAL(parsed[4].string_value(), "r"); - token = parsed[2].string_value(); + token = parsed[2].string_value().to_string(); // std::fprintf(stderr, "got token: %s\n", token.c_str()); } else @@ -671,7 +671,7 @@ TORRENT_TEST(get_peers_announce) if (ret) { TEST_CHECK(peer1_keys[0].string_value() == "r"); - token = peer1_keys[2].string_value(); + token = peer1_keys[2].string_value().to_string(); // std::fprintf(stderr, "got token: %s\n", token.c_str()); } else @@ -733,7 +733,7 @@ void test_scrape(address(&rand_addr)()) if (ret) { TEST_CHECK(peer1_keys[0].string_value() == "r"); - token = peer1_keys[2].string_value(); + token = peer1_keys[2].string_value().to_string(); } else { @@ -1091,7 +1091,7 @@ void test_put(address(&rand_addr)()) if (ret) { TEST_EQUAL(desc_keys[4].string_value(), "r"); - token = desc_keys[2].string_value(); + token = desc_keys[2].string_value().to_string(); std::fprintf(stderr, "get response: %s\n" , print_entry(response).c_str()); std::fprintf(stderr, "got token: %s\n", aux::to_hex(token).c_str()); diff --git a/test/test_resolve_links.cpp b/test/test_resolve_links.cpp index 3f17c97c8..aa64170e6 100644 --- a/test/test_resolve_links.cpp +++ b/test/test_resolve_links.cpp @@ -120,7 +120,9 @@ TORRENT_TEST(resolve_links) for (int i = 0; i < int(links.size()); ++i) { TORRENT_ASSERT(i < fs.num_files()); - std::fprintf(stderr, "%s --> %s : %d\n", fs.file_name(i).c_str() + std::fprintf(stderr, "%*s --> %s : %d\n" + , int(fs.file_name(i).size()) + , fs.file_name(i).data() , links[i].ti ? aux::to_hex(links[i].ti->info_hash()).c_str() : "", links[i].file_idx); } diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index d33481ae7..2b0ac7290 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -236,11 +236,11 @@ TORRENT_TEST(sanitize_long_path) sanitize_append_path_element(path, "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" - "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_", 250); + "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_"); sanitize_append_path_element(path, "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" - "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcde.test", 250); + "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcde.test"); TEST_EQUAL(path, "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" "abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_abcdefghi_" @@ -253,9 +253,9 @@ TORRENT_TEST(sanitize_long_path) TORRENT_TEST(sanitize_path_trailing_dots) { std::string path; - sanitize_append_path_element(path, "a", 1); - sanitize_append_path_element(path, "abc...", 6); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "a"); + sanitize_append_path_element(path, "abc..."); + sanitize_append_path_element(path, "c"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "a" SEPARATOR "abc" SEPARATOR "c"); #else @@ -263,7 +263,7 @@ TORRENT_TEST(sanitize_path_trailing_dots) #endif path.clear(); - sanitize_append_path_element(path, "abc...", 6); + sanitize_append_path_element(path, "abc..."); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "abc"); #else @@ -271,7 +271,7 @@ TORRENT_TEST(sanitize_path_trailing_dots) #endif path.clear(); - sanitize_append_path_element(path, "abc.", 4); + sanitize_append_path_element(path, "abc."); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "abc"); #else @@ -280,7 +280,7 @@ TORRENT_TEST(sanitize_path_trailing_dots) path.clear(); - sanitize_append_path_element(path, "a. . .", 6); + sanitize_append_path_element(path, "a. . ."); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "a"); #else @@ -291,9 +291,9 @@ TORRENT_TEST(sanitize_path_trailing_dots) TORRENT_TEST(sanitize_path_trailing_spaces) { std::string path; - sanitize_append_path_element(path, "a", 1); - sanitize_append_path_element(path, "abc ", 6); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "a"); + sanitize_append_path_element(path, "abc "); + sanitize_append_path_element(path, "c"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "a" SEPARATOR "abc" SEPARATOR "c"); #else @@ -301,7 +301,7 @@ TORRENT_TEST(sanitize_path_trailing_spaces) #endif path.clear(); - sanitize_append_path_element(path, "abc ", 6); + sanitize_append_path_element(path, "abc "); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "abc"); #else @@ -309,7 +309,7 @@ TORRENT_TEST(sanitize_path_trailing_spaces) #endif path.clear(); - sanitize_append_path_element(path, "abc ", 4); + sanitize_append_path_element(path, "abc "); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "abc"); #else @@ -320,34 +320,34 @@ TORRENT_TEST(sanitize_path_trailing_spaces) TORRENT_TEST(sanitize_path) { std::string path; - sanitize_append_path_element(path, "/a/", 3); - sanitize_append_path_element(path, "b", 1); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "/a/"); + sanitize_append_path_element(path, "b"); + sanitize_append_path_element(path, "c"); TEST_EQUAL(path, "a" SEPARATOR "b" SEPARATOR "c"); path.clear(); - sanitize_append_path_element(path, "a...b", 5); + sanitize_append_path_element(path, "a...b"); TEST_EQUAL(path, "a...b"); path.clear(); - sanitize_append_path_element(path, "a", 1); - sanitize_append_path_element(path, "..", 2); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "a"); + sanitize_append_path_element(path, ".."); + sanitize_append_path_element(path, "c"); TEST_EQUAL(path, "a" SEPARATOR "c"); path.clear(); - sanitize_append_path_element(path, "a", 1); - sanitize_append_path_element(path, "..", 2); + sanitize_append_path_element(path, "a"); + sanitize_append_path_element(path, ".."); TEST_EQUAL(path, "a"); path.clear(); - sanitize_append_path_element(path, "/..", 3); - sanitize_append_path_element(path, ".", 1); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "/.."); + sanitize_append_path_element(path, "."); + sanitize_append_path_element(path, "c"); TEST_EQUAL(path, "c"); path.clear(); - sanitize_append_path_element(path, "dev:", 4); + sanitize_append_path_element(path, "dev:"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "dev"); #else @@ -355,8 +355,8 @@ TORRENT_TEST(sanitize_path) #endif path.clear(); - sanitize_append_path_element(path, "c:", 2); - sanitize_append_path_element(path, "b", 1); + sanitize_append_path_element(path, "c:"); + sanitize_append_path_element(path, "b"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "c" SEPARATOR "b"); #else @@ -364,9 +364,9 @@ TORRENT_TEST(sanitize_path) #endif path.clear(); - sanitize_append_path_element(path, "c:", 2); - sanitize_append_path_element(path, ".", 1); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "c:"); + sanitize_append_path_element(path, "."); + sanitize_append_path_element(path, "c"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "c" SEPARATOR "c"); #else @@ -374,33 +374,33 @@ TORRENT_TEST(sanitize_path) #endif path.clear(); - sanitize_append_path_element(path, "\\c", 2); - sanitize_append_path_element(path, ".", 1); - sanitize_append_path_element(path, "c", 1); + sanitize_append_path_element(path, "\\c"); + sanitize_append_path_element(path, "."); + sanitize_append_path_element(path, "c"); TEST_EQUAL(path, "c" SEPARATOR "c"); path.clear(); - sanitize_append_path_element(path, "\b", 1); + sanitize_append_path_element(path, "\b"); TEST_EQUAL(path, "_"); path.clear(); - sanitize_append_path_element(path, "\b", 1); - sanitize_append_path_element(path, "filename", 8); + sanitize_append_path_element(path, "\b"); + sanitize_append_path_element(path, "filename"); TEST_EQUAL(path, "_" SEPARATOR "filename"); path.clear(); - sanitize_append_path_element(path, "filename", 8); - sanitize_append_path_element(path, "\b", 1); + sanitize_append_path_element(path, "filename"); + sanitize_append_path_element(path, "\b"); TEST_EQUAL(path, "filename" SEPARATOR "_"); path.clear(); - sanitize_append_path_element(path, "abc", 3); - sanitize_append_path_element(path, "", 0); + sanitize_append_path_element(path, "abc"); + sanitize_append_path_element(path, ""); TEST_EQUAL(path, "abc" SEPARATOR "_"); path.clear(); - sanitize_append_path_element(path, "abc", 3); - sanitize_append_path_element(path, " ", 3); + sanitize_append_path_element(path, "abc"); + sanitize_append_path_element(path, " "); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "abc"); #else @@ -408,12 +408,12 @@ TORRENT_TEST(sanitize_path) #endif path.clear(); - sanitize_append_path_element(path, "", 0); - sanitize_append_path_element(path, "abc", 3); + sanitize_append_path_element(path, ""); + sanitize_append_path_element(path, "abc"); TEST_EQUAL(path, "_" SEPARATOR "abc"); path.clear(); - sanitize_append_path_element(path, "\b?filename=4", 12); + sanitize_append_path_element(path, "\b?filename=4"); #ifdef TORRENT_WINDOWS TEST_EQUAL(path, "__filename=4"); #else @@ -421,65 +421,65 @@ TORRENT_TEST(sanitize_path) #endif path.clear(); - sanitize_append_path_element(path, "filename=4", 10); + sanitize_append_path_element(path, "filename=4"); TEST_EQUAL(path, "filename=4"); // valid 2-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xc2\xa1", 10); + sanitize_append_path_element(path, "filename\xc2\xa1"); TEST_EQUAL(path, "filename\xc2\xa1"); // truncated 2-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xc2", 9); + sanitize_append_path_element(path, "filename\xc2"); TEST_EQUAL(path, "filename_"); // valid 3-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xe2\x9f\xb9", 11); + sanitize_append_path_element(path, "filename\xe2\x9f\xb9"); TEST_EQUAL(path, "filename\xe2\x9f\xb9"); // truncated 3-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xe2\x9f", 10); + sanitize_append_path_element(path, "filename\xe2\x9f"); TEST_EQUAL(path, "filename_"); // truncated 3-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xe2", 9); + sanitize_append_path_element(path, "filename\xe2"); TEST_EQUAL(path, "filename_"); // valid 4-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xf0\x9f\x92\x88", 12); + sanitize_append_path_element(path, "filename\xf0\x9f\x92\x88"); TEST_EQUAL(path, "filename\xf0\x9f\x92\x88"); // truncated 4-byte sequence path.clear(); - sanitize_append_path_element(path, "filename\xf0\x9f\x92", 11); + sanitize_append_path_element(path, "filename\xf0\x9f\x92"); TEST_EQUAL(path, "filename_"); // 5-byte utf-8 sequence (not allowed) path.clear(); - sanitize_append_path_element(path, "filename\xf8\x9f\x9f\x9f\x9f" "foobar", 19); + sanitize_append_path_element(path, "filename\xf8\x9f\x9f\x9f\x9f" "foobar"); TEST_EQUAL(path, "filename_____foobar"); // redundant (overlong) 2-byte sequence // ascii code 0x2e encoded with a leading 0 path.clear(); - sanitize_append_path_element(path, "filename\xc0\xae", 10); + sanitize_append_path_element(path, "filename\xc0\xae"); TEST_EQUAL(path, "filename_"); // redundant (overlong) 3-byte sequence // ascii code 0x2e encoded with two leading 0s path.clear(); - sanitize_append_path_element(path, "filename\xe0\x80\xae", 11); + sanitize_append_path_element(path, "filename\xe0\x80\xae"); TEST_EQUAL(path, "filename_"); // redundant (overlong) 4-byte sequence // ascii code 0x2e encoded with three leading 0s path.clear(); - sanitize_append_path_element(path, "filename\xf0\x80\x80\xae", 12); + sanitize_append_path_element(path, "filename\xf0\x80\x80\xae"); TEST_EQUAL(path, "filename_"); } diff --git a/tools/fuzz_torrent.cpp b/tools/fuzz_torrent.cpp index cc4ce85b3..87f85f951 100644 --- a/tools/fuzz_torrent.cpp +++ b/tools/fuzz_torrent.cpp @@ -242,18 +242,18 @@ void render_variant(std::string& out, bdecode_node const& e) print_dict(out); for (int i = 0; i < e.dict_size(); ++i) { - std::pair item = e.dict_at(i); + std::pair item = e.dict_at(i); const bool duplicate = g_seed == 1; const bool skipped = g_seed == 2; g_seed -= 2; if (duplicate) { - print_string(out, item.first); + print_string(out, item.first.to_string()); render_variant(out, item.second); } if (!skipped) { - print_string(out, item.first); + print_string(out, item.first.to_string()); render_variant(out, item.second); } @@ -280,7 +280,7 @@ void render_variant(std::string& out, bdecode_node const& e) print_int(out, e.int_value()); break; case bdecode_node::string_t: - print_string(out, e.string_value()); + print_string(out, e.string_value().to_string()); break; default: abort();