wrap destination string in i2p_peer in string_ptr handler (#2268)
This commit is contained in:
parent
e92cbf502c
commit
d250ba5a17
|
@ -11,6 +11,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "bytes.hpp"
|
#include "bytes.hpp"
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_polymorphic.hpp>
|
||||||
|
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using namespace lt;
|
using namespace lt;
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ nobase_include_HEADERS = \
|
||||||
aux_/session_interface.hpp \
|
aux_/session_interface.hpp \
|
||||||
aux_/suggest_piece.hpp \
|
aux_/suggest_piece.hpp \
|
||||||
aux_/storage_piece_set.hpp \
|
aux_/storage_piece_set.hpp \
|
||||||
|
aux_/string_ptr.hpp \
|
||||||
aux_/time.hpp \
|
aux_/time.hpp \
|
||||||
aux_/file_progress.hpp \
|
aux_/file_progress.hpp \
|
||||||
aux_/openssl.hpp \
|
aux_/openssl.hpp \
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2017, 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_PTR_HPP_INCLUDED
|
||||||
|
#define TORRENT_STRING_PTR_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include "libtorrent/string_view.hpp"
|
||||||
|
|
||||||
|
namespace libtorrent {
|
||||||
|
namespace aux {
|
||||||
|
|
||||||
|
struct string_ptr
|
||||||
|
{
|
||||||
|
explicit string_ptr(string_view str) : m_ptr(new char[str.size() + 1])
|
||||||
|
{
|
||||||
|
std::copy(str.begin(), str.end(), m_ptr);
|
||||||
|
m_ptr[str.size()] = '\0';
|
||||||
|
}
|
||||||
|
~string_ptr()
|
||||||
|
{
|
||||||
|
delete[] m_ptr;
|
||||||
|
}
|
||||||
|
string_ptr(string_ptr&& rhs)
|
||||||
|
: m_ptr(rhs.m_ptr)
|
||||||
|
{
|
||||||
|
rhs.m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
string_ptr& operator=(string_ptr&& rhs)
|
||||||
|
{
|
||||||
|
if (&rhs == this) return *this;
|
||||||
|
delete[] m_ptr;
|
||||||
|
m_ptr = rhs.m_ptr;
|
||||||
|
rhs.m_ptr = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
string_ptr(string_ptr const& rhs) = delete;
|
||||||
|
string_ptr& operator=(string_ptr const& rhs) = delete;
|
||||||
|
char const* operator*() const { return m_ptr; }
|
||||||
|
private:
|
||||||
|
char* m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
|
|
||||||
void set_session_id(char const* id) { m_id = id; }
|
void set_session_id(char const* id) { m_id = id; }
|
||||||
|
|
||||||
void set_destination(std::string const& d) { m_dest = d; }
|
void set_destination(string_view d) { m_dest = d.to_string(); }
|
||||||
std::string const& destination() { return m_dest; }
|
std::string const& destination() { return m_dest; }
|
||||||
|
|
||||||
template <class Handler>
|
template <class Handler>
|
||||||
|
|
|
@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/peer_connection_interface.hpp"
|
#include "libtorrent/peer_connection_interface.hpp"
|
||||||
#include "libtorrent/aux_/deque.hpp"
|
#include "libtorrent/aux_/deque.hpp"
|
||||||
#include "libtorrent/peer_info.hpp" // for peer_source_flags_t
|
#include "libtorrent/peer_info.hpp" // for peer_source_flags_t
|
||||||
|
#include "libtorrent/string_view.hpp"
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
|
@ -113,7 +114,7 @@ namespace libtorrent {
|
||||||
peer_list();
|
peer_list();
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
torrent_peer* add_i2p_peer(char const* destination
|
torrent_peer* add_i2p_peer(string_view destination
|
||||||
, peer_source_flags_t src, char flags
|
, peer_source_flags_t src, char flags
|
||||||
, torrent_state* state);
|
, torrent_state* state);
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,7 +214,7 @@ namespace libtorrent {
|
||||||
void update_connect_candidates(int delta);
|
void update_connect_candidates(int delta);
|
||||||
|
|
||||||
void update_peer(torrent_peer* p, peer_source_flags_t src, int flags
|
void update_peer(torrent_peer* p, peer_source_flags_t src, int flags
|
||||||
, tcp::endpoint const& remote, char const* destination);
|
, tcp::endpoint const& remote);
|
||||||
bool insert_peer(torrent_peer* p, iterator iter, int flags, torrent_state* state);
|
bool insert_peer(torrent_peer* p, iterator iter, int flags, torrent_state* state);
|
||||||
|
|
||||||
bool compare_peer_erase(torrent_peer const& lhs, torrent_peer const& rhs) const;
|
bool compare_peer_erase(torrent_peer const& lhs, torrent_peer const& rhs) const;
|
||||||
|
|
|
@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/address.hpp"
|
#include "libtorrent/address.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_info.hpp" // for peer_source_flags_t
|
#include "libtorrent/peer_info.hpp" // for peer_source_flags_t
|
||||||
|
#include "libtorrent/aux_/string_ptr.hpp"
|
||||||
|
#include "libtorrent/string_view.hpp"
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
|
@ -59,7 +61,7 @@ namespace libtorrent {
|
||||||
std::uint32_t rank(external_ip const& external, int external_port) const;
|
std::uint32_t rank(external_ip const& external, int external_port) const;
|
||||||
|
|
||||||
libtorrent::address address() const;
|
libtorrent::address address() const;
|
||||||
char const* dest() const;
|
string_view dest() const;
|
||||||
|
|
||||||
tcp::endpoint ip() const { return tcp::endpoint(address(), port); }
|
tcp::endpoint ip() const { return tcp::endpoint(address(), port); }
|
||||||
|
|
||||||
|
@ -213,12 +215,13 @@ namespace libtorrent {
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
struct TORRENT_EXTRA_EXPORT i2p_peer : torrent_peer
|
struct TORRENT_EXTRA_EXPORT i2p_peer : torrent_peer
|
||||||
{
|
{
|
||||||
i2p_peer(char const* destination, bool connectable, peer_source_flags_t src);
|
i2p_peer(string_view dst, bool connectable, peer_source_flags_t src);
|
||||||
i2p_peer(i2p_peer const&);
|
i2p_peer(i2p_peer const&) = delete;
|
||||||
~i2p_peer();
|
i2p_peer& operator=(i2p_peer const&) = delete;
|
||||||
i2p_peer& operator=(i2p_peer const&);
|
i2p_peer(i2p_peer&&) = default;
|
||||||
|
i2p_peer& operator=(i2p_peer&&) = default;
|
||||||
|
|
||||||
char* destination;
|
aux::string_ptr destination;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -234,38 +237,33 @@ namespace libtorrent {
|
||||||
|
|
||||||
struct peer_address_compare
|
struct peer_address_compare
|
||||||
{
|
{
|
||||||
bool operator()(
|
bool operator()(torrent_peer const* lhs, address const& rhs) const
|
||||||
torrent_peer const* lhs, libtorrent::address const& rhs) const
|
|
||||||
{
|
{
|
||||||
return lhs->address() < rhs;
|
return lhs->address() < rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(
|
bool operator()(address const& lhs, torrent_peer const* rhs) const
|
||||||
libtorrent::address const& lhs, torrent_peer const* rhs) const
|
|
||||||
{
|
{
|
||||||
return lhs < rhs->address();
|
return lhs < rhs->address();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
bool operator()(
|
bool operator()(torrent_peer const* lhs, string_view rhs) const
|
||||||
torrent_peer const* lhs, char const* rhs) const
|
|
||||||
{
|
{
|
||||||
return strcmp(lhs->dest(), rhs) < 0;
|
return lhs->dest().compare(rhs) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(
|
bool operator()(string_view lhs, torrent_peer const* rhs) const
|
||||||
char const* lhs, torrent_peer const* rhs) const
|
|
||||||
{
|
{
|
||||||
return strcmp(lhs, rhs->dest()) < 0;
|
return lhs.compare(rhs->dest()) < 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool operator()(
|
bool operator()(torrent_peer const* lhs, torrent_peer const* rhs) const
|
||||||
torrent_peer const* lhs, torrent_peer const* rhs) const
|
|
||||||
{
|
{
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
if (rhs->is_i2p_addr == lhs->is_i2p_addr)
|
if (rhs->is_i2p_addr == lhs->is_i2p_addr)
|
||||||
return strcmp(lhs->dest(), rhs->dest()) < 0;
|
return lhs->dest().compare(rhs->dest()) < 0;
|
||||||
#endif
|
#endif
|
||||||
return lhs->address() < rhs->address();
|
return lhs->address() < rhs->address();
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,8 +952,7 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_list::update_peer(torrent_peer* p, peer_source_flags_t const src
|
void peer_list::update_peer(torrent_peer* p, peer_source_flags_t const src
|
||||||
, int flags
|
, int flags, tcp::endpoint const& remote)
|
||||||
, tcp::endpoint const& remote, char const* /* destination*/)
|
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
bool const was_conn_cand = is_connect_candidate(*p);
|
bool const was_conn_cand = is_connect_candidate(*p);
|
||||||
|
@ -1008,50 +1007,40 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
// TODO: 3 use string_view for destination
|
torrent_peer* peer_list::add_i2p_peer(string_view const destination
|
||||||
torrent_peer* peer_list::add_i2p_peer(char const* destination
|
|
||||||
, peer_source_flags_t const src, char flags, torrent_state* state)
|
, peer_source_flags_t const src, char flags, torrent_state* state)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
bool found = false;
|
iterator iter = std::lower_bound(m_peers.begin(), m_peers.end()
|
||||||
iterator iter = std::lower_bound(
|
, destination, peer_address_compare());
|
||||||
m_peers.begin(), m_peers.end()
|
|
||||||
, destination, peer_address_compare()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (iter != m_peers.end() && strcmp((*iter)->dest(), destination) == 0)
|
if (iter != m_peers.end() && (*iter)->dest() == destination)
|
||||||
found = true;
|
|
||||||
|
|
||||||
torrent_peer* p = nullptr;
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
{
|
||||||
// we don't have any info about this peer.
|
update_peer(*iter, src, flags, tcp::endpoint());
|
||||||
// add a new entry
|
return *iter;
|
||||||
p = state->peer_allocator->allocate_peer_entry(torrent_peer_allocator_interface::i2p_peer_type);
|
|
||||||
if (p == nullptr) return nullptr;
|
|
||||||
new (p) i2p_peer(destination, true, src);
|
|
||||||
|
|
||||||
#if TORRENT_USE_ASSERTS
|
|
||||||
p->in_use = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!insert_peer(p, iter, flags, state))
|
|
||||||
{
|
|
||||||
#if TORRENT_USE_ASSERTS
|
|
||||||
p->in_use = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
state->peer_allocator->free_peer_entry(p);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// we don't have any info about this peer.
|
||||||
|
// add a new entry
|
||||||
|
torrent_peer* p = state->peer_allocator->allocate_peer_entry(
|
||||||
|
torrent_peer_allocator_interface::i2p_peer_type);
|
||||||
|
if (p == nullptr) return nullptr;
|
||||||
|
new (p) i2p_peer(destination, true, src);
|
||||||
|
|
||||||
|
#if TORRENT_USE_ASSERTS
|
||||||
|
p->in_use = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!insert_peer(p, iter, flags, state))
|
||||||
{
|
{
|
||||||
p = *iter;
|
#if TORRENT_USE_ASSERTS
|
||||||
update_peer(p, src, flags, tcp::endpoint(), destination);
|
p->in_use = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
state->peer_allocator->free_peer_entry(p);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -1089,10 +1078,8 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iter = std::lower_bound(
|
iter = std::lower_bound(m_peers.begin(), m_peers.end()
|
||||||
m_peers.begin(), m_peers.end()
|
, remote.address(), peer_address_compare());
|
||||||
, remote.address(), peer_address_compare()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (iter != m_peers.end() && (*iter)->address() == remote.address()) found = true;
|
if (iter != m_peers.end() && (*iter)->address() == remote.address()) found = true;
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1124,7 @@ namespace libtorrent {
|
||||||
{
|
{
|
||||||
p = *iter;
|
p = *iter;
|
||||||
TORRENT_ASSERT(p->in_use);
|
TORRENT_ASSERT(p->in_use);
|
||||||
update_peer(p, src, flags, remote, nullptr);
|
update_peer(p, src, flags, remote);
|
||||||
state->first_time_seen = false;
|
state->first_time_seen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6509,7 +6509,7 @@ namespace libtorrent {
|
||||||
, m_ses.i2p_proxy(), *s, nullptr, nullptr, false, false);
|
, m_ses.i2p_proxy(), *s, nullptr, nullptr, false, false);
|
||||||
(void)ret;
|
(void)ret;
|
||||||
TORRENT_ASSERT(ret);
|
TORRENT_ASSERT(ret);
|
||||||
s->get<i2p_stream>()->set_destination(static_cast<i2p_peer*>(peerinfo)->destination);
|
s->get<i2p_stream>()->set_destination(static_cast<i2p_peer*>(peerinfo)->dest());
|
||||||
s->get<i2p_stream>()->set_command(i2p_stream::cmd_connect);
|
s->get<i2p_stream>()->set_command(i2p_stream::cmd_connect);
|
||||||
s->get<i2p_stream>()->set_session_id(m_ses.i2p_session());
|
s->get<i2p_stream>()->set_session_id(m_ses.i2p_session());
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ namespace libtorrent {
|
||||||
std::string torrent_peer::to_string() const
|
std::string torrent_peer::to_string() const
|
||||||
{
|
{
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
if (is_i2p_addr) return dest();
|
if (is_i2p_addr) return dest().to_string();
|
||||||
#endif // TORRENT_USE_I2P
|
#endif // TORRENT_USE_I2P
|
||||||
error_code ec;
|
error_code ec;
|
||||||
return address().to_string(ec);
|
return address().to_string(ec);
|
||||||
|
@ -246,31 +246,16 @@ namespace libtorrent {
|
||||||
ipv4_peer& ipv4_peer::operator=(ipv4_peer const& p) = default;
|
ipv4_peer& ipv4_peer::operator=(ipv4_peer const& p) = default;
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
i2p_peer::i2p_peer(char const* dest, bool connectable
|
i2p_peer::i2p_peer(string_view dest, bool connectable
|
||||||
, peer_source_flags_t const src)
|
, peer_source_flags_t const src)
|
||||||
: torrent_peer(0, connectable, src), destination(allocate_string_copy(dest))
|
: torrent_peer(0, connectable, src)
|
||||||
|
, destination(dest)
|
||||||
{
|
{
|
||||||
#if TORRENT_USE_IPV6
|
#if TORRENT_USE_IPV6
|
||||||
is_v6_addr = false;
|
is_v6_addr = false;
|
||||||
#endif
|
#endif
|
||||||
is_i2p_addr = true;
|
is_i2p_addr = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2p_peer::~i2p_peer()
|
|
||||||
{ free(destination); }
|
|
||||||
|
|
||||||
i2p_peer::i2p_peer(const i2p_peer& rhs)
|
|
||||||
: torrent_peer(rhs.port, rhs.connectable, rhs.peer_source())
|
|
||||||
, destination(allocate_string_copy(rhs.destination))
|
|
||||||
{}
|
|
||||||
|
|
||||||
i2p_peer& i2p_peer::operator=(i2p_peer const& rhs)
|
|
||||||
{
|
|
||||||
char* tmp = allocate_string_copy(rhs.destination);
|
|
||||||
free(destination);
|
|
||||||
destination = tmp;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif // TORRENT_USE_I2P
|
#endif // TORRENT_USE_I2P
|
||||||
|
|
||||||
#if TORRENT_USE_IPV6
|
#if TORRENT_USE_IPV6
|
||||||
|
@ -290,10 +275,10 @@ namespace libtorrent {
|
||||||
#endif // TORRENT_USE_IPV6
|
#endif // TORRENT_USE_IPV6
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
char const* torrent_peer::dest() const
|
string_view torrent_peer::dest() const
|
||||||
{
|
{
|
||||||
if (is_i2p_addr)
|
if (is_i2p_addr)
|
||||||
return static_cast<i2p_peer const*>(this)->destination;
|
return *static_cast<i2p_peer const*>(this)->destination;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/aux_/escape_string.hpp"
|
#include "libtorrent/aux_/escape_string.hpp"
|
||||||
#include "libtorrent/hex.hpp"
|
#include "libtorrent/hex.hpp"
|
||||||
#include "libtorrent/string_util.hpp"
|
#include "libtorrent/string_util.hpp"
|
||||||
|
#include "libtorrent/aux_/string_ptr.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring> // for strcmp
|
#include <cstring> // for strcmp
|
||||||
#include "libtorrent/aux_/escape_string.hpp" // for trim
|
#include "libtorrent/aux_/escape_string.hpp" // for trim
|
||||||
|
@ -448,3 +449,42 @@ TORRENT_TEST(string_eq_no_case)
|
||||||
TEST_CHECK(cmp(std::string("\0a", 2), std::string("\0a", 2)));
|
TEST_CHECK(cmp(std::string("\0a", 2), std::string("\0a", 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(string_ptr_zero_termination)
|
||||||
|
{
|
||||||
|
char str[] = {'f', 'o', 'o', 'b', 'a', 'r'};
|
||||||
|
aux::string_ptr p(string_view(str, sizeof(str)));
|
||||||
|
|
||||||
|
// make sure it's zero-terminated now
|
||||||
|
TEST_CHECK(strlen(*p) == 6);
|
||||||
|
TEST_CHECK((*p)[6] == '\0');
|
||||||
|
TEST_CHECK(*p == string_view("foobar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(string_ptr_move_construct)
|
||||||
|
{
|
||||||
|
aux::string_ptr p1("test");
|
||||||
|
TEST_CHECK(*p1 == string_view("test"));
|
||||||
|
|
||||||
|
aux::string_ptr p2(std::move(p1));
|
||||||
|
|
||||||
|
TEST_CHECK(*p2 == string_view("test"));
|
||||||
|
|
||||||
|
// moved-from state is empty
|
||||||
|
TEST_CHECK(*p1 == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(string_ptr_move_assign)
|
||||||
|
{
|
||||||
|
aux::string_ptr p1("test");
|
||||||
|
TEST_CHECK(*p1 == string_view("test"));
|
||||||
|
|
||||||
|
aux::string_ptr p2("foobar");
|
||||||
|
|
||||||
|
p1 = std::move(p2);
|
||||||
|
|
||||||
|
TEST_CHECK(*p1 == string_view("foobar"));
|
||||||
|
|
||||||
|
// moved-from state is empty
|
||||||
|
TEST_CHECK(*p2 == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue