Span conversion (#944)
complete http_parser transition to use span. make xml_parse use span. remove buffer::interval. convert some of receive buffer management to use span<>
This commit is contained in:
parent
680a09cfa5
commit
634c2bce60
|
@ -286,7 +286,7 @@ namespace libtorrent
|
||||||
, char const* target, int target_size) const;
|
, char const* target, int target_size) const;
|
||||||
|
|
||||||
// helper to cut down on boilerplate
|
// helper to cut down on boilerplate
|
||||||
void rc4_decrypt(char* pos, int len);
|
void rc4_decrypt(span<char> buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -75,43 +75,8 @@ class buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// TODO: 3 remove interval and const_interval
|
|
||||||
struct interval
|
|
||||||
{
|
|
||||||
interval()
|
|
||||||
: begin(0)
|
|
||||||
, end(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
interval(char* b, char* e)
|
|
||||||
: begin(b)
|
|
||||||
, end(e)
|
|
||||||
{}
|
|
||||||
|
|
||||||
char operator[](int index) const
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(begin + index < end);
|
|
||||||
return begin[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int left() const
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(end >= begin);
|
|
||||||
TORRENT_ASSERT(end - begin < (std::numeric_limits<int>::max)());
|
|
||||||
return int(end - begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* begin;
|
|
||||||
char* end;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct const_interval
|
struct const_interval
|
||||||
{
|
{
|
||||||
const_interval(interval const& i)
|
|
||||||
: begin(i.begin)
|
|
||||||
, end(i.end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const_interval(char const* b, char const* e)
|
const_interval(char const* b, char const* e)
|
||||||
: begin(b)
|
: begin(b)
|
||||||
, end(e)
|
, end(e)
|
||||||
|
|
|
@ -85,6 +85,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void pop_front(int bytes_to_pop);
|
void pop_front(int bytes_to_pop);
|
||||||
|
|
||||||
|
//TODO: 3 use span<> instead of (buffer,s)
|
||||||
void append_buffer(char* buffer, int s, int used_size
|
void append_buffer(char* buffer, int s, int used_size
|
||||||
, free_buffer_fun destructor, void* userdata
|
, free_buffer_fun destructor, void* userdata
|
||||||
, block_cache_reference ref = block_cache_reference());
|
, block_cache_reference ref = block_cache_reference());
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace libtorrent
|
||||||
std::string const& method() const { return m_method; }
|
std::string const& method() const { return m_method; }
|
||||||
std::string const& path() const { return m_path; }
|
std::string const& path() const { return m_path; }
|
||||||
std::string const& message() const { return m_server_message; }
|
std::string const& message() const { return m_server_message; }
|
||||||
buffer::const_interval get_body() const;
|
span<char const> get_body() const;
|
||||||
bool header_finished() const { return m_state == read_body; }
|
bool header_finished() const { return m_state == read_body; }
|
||||||
bool finished() const { return m_finished; }
|
bool finished() const { return m_finished; }
|
||||||
std::tuple<int, int> incoming(span<char const> recv_buffer
|
std::tuple<int, int> incoming(span<char const> recv_buffer
|
||||||
|
|
|
@ -89,8 +89,9 @@ struct TORRENT_EXTRA_EXPORT receive_buffer
|
||||||
buffer::const_interval get() const;
|
buffer::const_interval get() const;
|
||||||
|
|
||||||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||||
// returns the entire buffer
|
// returns the buffer from the current packet start position to the last
|
||||||
buffer::interval mutable_buffer();
|
// received byte (possibly part of another packet)
|
||||||
|
span<char> mutable_buffer();
|
||||||
|
|
||||||
// returns the last 'bytes' from the receive buffer
|
// returns the last 'bytes' from the receive buffer
|
||||||
aux::mutable_buffer mutable_buffer(int bytes);
|
aux::mutable_buffer mutable_buffer(int bytes);
|
||||||
|
@ -107,6 +108,9 @@ struct TORRENT_EXTRA_EXPORT receive_buffer
|
||||||
void check_invariant() const
|
void check_invariant() const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_recv_end >= m_recv_start);
|
TORRENT_ASSERT(m_recv_end >= m_recv_start);
|
||||||
|
TORRENT_ASSERT(m_recv_end <= int(m_recv_buffer.size()));
|
||||||
|
TORRENT_ASSERT(m_recv_start <= int(m_recv_buffer.size()));
|
||||||
|
TORRENT_ASSERT(m_recv_start + m_recv_pos <= int(m_recv_buffer.size()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -116,7 +120,7 @@ private:
|
||||||
|
|
||||||
// m_recv_buffer.data() (start of actual receive buffer)
|
// m_recv_buffer.data() (start of actual receive buffer)
|
||||||
// |
|
// |
|
||||||
// | m_recv_start (tart of current packet)
|
// | m_recv_start (start of current packet)
|
||||||
// | |
|
// | |
|
||||||
// | | m_recv_pos (number of bytes consumed
|
// | | m_recv_pos (number of bytes consumed
|
||||||
// | | | by upper layer, from logical receive buffer)
|
// | | | by upper layer, from logical receive buffer)
|
||||||
|
@ -167,7 +171,7 @@ struct crypto_receive_buffer
|
||||||
: m_connection_buffer(next)
|
: m_connection_buffer(next)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
buffer::interval mutable_buffer() { return m_connection_buffer.mutable_buffer(); }
|
span<char> mutable_buffer() { return m_connection_buffer.mutable_buffer(); }
|
||||||
|
|
||||||
bool packet_finished() const;
|
bool packet_finished() const;
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_XML_PARSE_HPP
|
#ifndef TORRENT_XML_PARSE_HPP
|
||||||
#define TORRENT_XML_PARSE_HPP
|
#define TORRENT_XML_PARSE_HPP
|
||||||
|
|
||||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
#include "libtorrent/span.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -68,7 +69,8 @@ namespace libtorrent
|
||||||
// val is attribute value
|
// val is attribute value
|
||||||
// neither string is 0-terminated, but their lengths are specified via
|
// neither string is 0-terminated, but their lengths are specified via
|
||||||
// name_len and val_len respectively
|
// name_len and val_len respectively
|
||||||
TORRENT_EXTRA_EXPORT void xml_parse(char const* p, char const* end
|
// TODO: 3 use span<> for the callback
|
||||||
|
TORRENT_EXTRA_EXPORT void xml_parse(span<char const> input
|
||||||
, boost::function<void(int,char const*,int,char const*,int)> callback);
|
, boost::function<void(int,char const*,int,char const*,int)> callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -700,20 +700,19 @@ namespace libtorrent
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::rc4_decrypt(char* const pos, int const len)
|
void bt_peer_connection::rc4_decrypt(span<char> buf)
|
||||||
{
|
{
|
||||||
int consume = 0;
|
int consume = 0;
|
||||||
int produce = len;
|
int produce = int(buf.size());
|
||||||
int packet_size = 0;
|
int packet_size = 0;
|
||||||
aux::mutable_buffer vec(pos, len);
|
m_rc4->decrypt(buf, consume, produce, packet_size);
|
||||||
m_rc4->decrypt(vec, consume, produce, packet_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void regular_c_free(char* buf, void* /* userdata */
|
void regular_c_free(char* buf, void* /* userdata */
|
||||||
, block_cache_reference /* ref */)
|
, block_cache_reference /* ref */)
|
||||||
{
|
{
|
||||||
::free(buf);
|
std::free(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,7 +727,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
// if we're encrypting this buffer, we need to make a copy
|
// if we're encrypting this buffer, we need to make a copy
|
||||||
// since we'll mutate it
|
// since we'll mutate it
|
||||||
char* buf = static_cast<char*>(malloc(size));
|
char* buf = static_cast<char*>(std::malloc(size));
|
||||||
std::memcpy(buf, buffer, size);
|
std::memcpy(buf, buffer, size);
|
||||||
append_send_buffer(buf, size, ®ular_c_free, nullptr);
|
append_send_buffer(buf, size, ®ular_c_free, nullptr);
|
||||||
destructor(const_cast<char*>(buffer), userdata, ref);
|
destructor(const_cast<char*>(buffer), userdata, ref);
|
||||||
|
@ -2735,9 +2734,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify constant
|
// verify constant
|
||||||
buffer::interval wr_recv_buf = m_recv_buffer.mutable_buffer();
|
rc4_decrypt(m_recv_buffer.mutable_buffer().subspan(20, 8));
|
||||||
rc4_decrypt(wr_recv_buf.begin + 20, 8);
|
|
||||||
wr_recv_buf.begin += 28;
|
|
||||||
|
|
||||||
const char sh_vc[] = {0,0,0,0, 0,0,0,0};
|
const char sh_vc[] = {0,0,0,0, 0,0,0,0};
|
||||||
if (!std::equal(sh_vc, sh_vc + 8, recv_buffer.begin + 20))
|
if (!std::equal(sh_vc, sh_vc + 8, recv_buffer.begin + 20))
|
||||||
|
@ -2781,7 +2778,7 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::fill(m_sync_vc.get(), m_sync_vc.get() + 8, 0);
|
std::fill(m_sync_vc.get(), m_sync_vc.get() + 8, 0);
|
||||||
rc4_decrypt(m_sync_vc.get(), 8);
|
rc4_decrypt({m_sync_vc.get(), 8});
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_ASSERT(m_sync_vc.get());
|
TORRENT_ASSERT(m_sync_vc.get());
|
||||||
|
@ -2839,8 +2836,10 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!m_recv_buffer.packet_finished()) return;
|
if (!m_recv_buffer.packet_finished()) return;
|
||||||
|
|
||||||
buffer::interval wr_buf = m_recv_buffer.mutable_buffer();
|
// TODO: 3 this is weird buffer handling
|
||||||
rc4_decrypt(wr_buf.begin, m_recv_buffer.packet_size());
|
span<char> const buf = m_recv_buffer.mutable_buffer();
|
||||||
|
TORRENT_ASSERT(buf.size() >= m_recv_buffer.packet_size());
|
||||||
|
rc4_decrypt({buf.data(), size_t(m_recv_buffer.packet_size())});
|
||||||
|
|
||||||
recv_buffer = m_recv_buffer.get();
|
recv_buffer = m_recv_buffer.get();
|
||||||
|
|
||||||
|
@ -2944,8 +2943,10 @@ namespace libtorrent
|
||||||
|
|
||||||
int const pad_size = is_outgoing() ? m_recv_buffer.packet_size() : m_recv_buffer.packet_size() - 2;
|
int const pad_size = is_outgoing() ? m_recv_buffer.packet_size() : m_recv_buffer.packet_size() - 2;
|
||||||
|
|
||||||
buffer::interval wr_buf = m_recv_buffer.mutable_buffer();
|
// TODO: 3 this is weird buffer handling
|
||||||
rc4_decrypt(wr_buf.begin, m_recv_buffer.packet_size());
|
span<char> const buf = m_recv_buffer.mutable_buffer();
|
||||||
|
TORRENT_ASSERT(buf.size() >= m_recv_buffer.packet_size());
|
||||||
|
rc4_decrypt({buf.data(), size_t(m_recv_buffer.packet_size())});
|
||||||
|
|
||||||
recv_buffer = m_recv_buffer.get();
|
recv_buffer = m_recv_buffer.get();
|
||||||
|
|
||||||
|
@ -3003,8 +3004,10 @@ namespace libtorrent
|
||||||
if (!m_recv_buffer.packet_finished()) return;
|
if (!m_recv_buffer.packet_finished()) return;
|
||||||
|
|
||||||
// ia is always rc4, so decrypt it
|
// ia is always rc4, so decrypt it
|
||||||
buffer::interval wr_buf = m_recv_buffer.mutable_buffer();
|
// TODO: 3 this is weird buffer handling
|
||||||
rc4_decrypt(wr_buf.begin, m_recv_buffer.packet_size());
|
span<char> const buf = m_recv_buffer.mutable_buffer();
|
||||||
|
TORRENT_ASSERT(buf.size() >= m_recv_buffer.packet_size());
|
||||||
|
rc4_decrypt({buf.data(), size_t(m_recv_buffer.packet_size())});
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
peer_log(peer_log_alert::info, "ENCRYPTION"
|
peer_log(peer_log_alert::info, "ENCRYPTION"
|
||||||
|
@ -3033,13 +3036,13 @@ namespace libtorrent
|
||||||
// decrypt remaining received bytes
|
// decrypt remaining received bytes
|
||||||
if (m_rc4_encrypted)
|
if (m_rc4_encrypted)
|
||||||
{
|
{
|
||||||
buffer::interval wr_buf = m_recv_buffer.mutable_buffer();
|
span<char> const remaining = m_recv_buffer.mutable_buffer()
|
||||||
wr_buf.begin += m_recv_buffer.packet_size();
|
.subspan(m_recv_buffer.packet_size());
|
||||||
rc4_decrypt(wr_buf.begin, wr_buf.left());
|
rc4_decrypt(remaining);
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
peer_log(peer_log_alert::info, "ENCRYPTION"
|
peer_log(peer_log_alert::info, "ENCRYPTION"
|
||||||
, "decrypted remaining %d bytes", wr_buf.left());
|
, "decrypted remaining %d bytes", int(remaining.size()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_rc4.reset();
|
m_rc4.reset();
|
||||||
|
|
|
@ -622,6 +622,7 @@ void http_connection::on_connect(error_code const& e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: 3 use span<char> instead of data, size
|
||||||
void http_connection::callback(error_code e, char* data, int size)
|
void http_connection::callback(error_code e, char* data, int size)
|
||||||
{
|
{
|
||||||
if (m_bottled && m_called) return;
|
if (m_bottled && m_called) return;
|
||||||
|
@ -720,14 +721,13 @@ void http_connection::on_read(error_code const& e
|
||||||
{
|
{
|
||||||
error_code ec = boost::asio::error::eof;
|
error_code ec = boost::asio::error::eof;
|
||||||
TORRENT_ASSERT(bytes_transferred == 0);
|
TORRENT_ASSERT(bytes_transferred == 0);
|
||||||
char* data = nullptr;
|
span<char> body;
|
||||||
std::size_t size = 0;
|
|
||||||
if (m_bottled && m_parser.header_finished())
|
if (m_bottled && m_parser.header_finished())
|
||||||
{
|
{
|
||||||
data = &m_recvbuffer[0] + m_parser.body_start();
|
body = span<char>(m_recvbuffer.data() + m_parser.body_start()
|
||||||
size = m_parser.get_body().left();
|
, m_parser.get_body().size());
|
||||||
}
|
}
|
||||||
callback(ec, data, int(size));
|
callback(ec, body.data(), int(body.size()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +802,9 @@ void http_connection::on_read(error_code const& e
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
m_timer.cancel(ec);
|
m_timer.cancel(ec);
|
||||||
callback(e, &m_recvbuffer[0] + m_parser.body_start(), m_parser.get_body().left());
|
span<char> body(m_recvbuffer.data() + m_parser.body_start()
|
||||||
|
, m_parser.get_body().size());
|
||||||
|
callback(e, body.data(), int(body.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -518,18 +518,16 @@ restart_response:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::const_interval http_parser::get_body() const
|
span<char const> http_parser::get_body() const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_state == read_body);
|
TORRENT_ASSERT(m_state == read_body);
|
||||||
std::int64_t last_byte = m_chunked_encoding && !m_chunked_ranges.empty()
|
std::int64_t const received = m_recv_pos - m_body_start_pos;
|
||||||
? (std::min)(m_chunked_ranges.back().second, m_recv_pos)
|
|
||||||
: m_content_length < 0
|
|
||||||
? m_recv_pos : (std::min)(m_body_start_pos + m_content_length, m_recv_pos);
|
|
||||||
|
|
||||||
TORRENT_ASSERT(last_byte >= m_body_start_pos);
|
std::int64_t const body_length = m_chunked_encoding && !m_chunked_ranges.empty()
|
||||||
return buffer::const_interval(m_recv_buffer.data()
|
? (std::min)(m_chunked_ranges.back().second - m_body_start_pos, received)
|
||||||
+ m_body_start_pos
|
: m_content_length < 0 ? received : (std::min)(m_content_length, received);
|
||||||
, m_recv_buffer.data() + last_byte);
|
|
||||||
|
return m_recv_buffer.subspan(m_body_start_pos, body_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_parser::reset()
|
void http_parser::reset()
|
||||||
|
@ -563,7 +561,7 @@ restart_response:
|
||||||
// the offsets in the array are from the start of the
|
// the offsets in the array are from the start of the
|
||||||
// buffer, not start of the body, so subtract the size
|
// buffer, not start of the body, so subtract the size
|
||||||
// of the HTTP header from them
|
// of the HTTP header from them
|
||||||
int offset = body_start();
|
int const offset = body_start();
|
||||||
std::vector<std::pair<std::int64_t, std::int64_t> > const& c = chunks();
|
std::vector<std::pair<std::int64_t, std::int64_t> > const& c = chunks();
|
||||||
for (std::vector<std::pair<std::int64_t, std::int64_t> >::const_iterator i = c.begin()
|
for (std::vector<std::pair<std::int64_t, std::int64_t> >::const_iterator i = c.begin()
|
||||||
, end(c.end()); i != end; ++i)
|
, end(c.end()); i != end; ++i)
|
||||||
|
|
|
@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libtorrent/receive_buffer.hpp>
|
#include <libtorrent/receive_buffer.hpp>
|
||||||
|
#include <libtorrent/invariant_check.hpp>
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ int receive_buffer::max_receive() const
|
||||||
|
|
||||||
boost::asio::mutable_buffer receive_buffer::reserve(int size)
|
boost::asio::mutable_buffer receive_buffer::reserve(int size)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(size > 0);
|
TORRENT_ASSERT(size > 0);
|
||||||
TORRENT_ASSERT(m_recv_pos >= 0);
|
TORRENT_ASSERT(m_recv_pos >= 0);
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ boost::asio::mutable_buffer receive_buffer::reserve(int size)
|
||||||
|
|
||||||
void receive_buffer::grow(int const limit)
|
void receive_buffer::grow(int const limit)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
int const current_size = int(m_recv_buffer.size());
|
int const current_size = int(m_recv_buffer.size());
|
||||||
TORRENT_ASSERT(current_size < std::numeric_limits<int>::max() / 3);
|
TORRENT_ASSERT(current_size < std::numeric_limits<int>::max() / 3);
|
||||||
|
|
||||||
|
@ -83,6 +86,7 @@ void receive_buffer::grow(int const limit)
|
||||||
|
|
||||||
int receive_buffer::advance_pos(int bytes)
|
int receive_buffer::advance_pos(int bytes)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
int const limit = m_packet_size > m_recv_pos ? m_packet_size - m_recv_pos : m_packet_size;
|
int const limit = m_packet_size > m_recv_pos ? m_packet_size - m_recv_pos : m_packet_size;
|
||||||
int const sub_transferred = (std::min)(bytes, limit);
|
int const sub_transferred = (std::min)(bytes, limit);
|
||||||
m_recv_pos += sub_transferred;
|
m_recv_pos += sub_transferred;
|
||||||
|
@ -94,6 +98,7 @@ int receive_buffer::advance_pos(int bytes)
|
||||||
// offset = the offset into the receive buffer where to remove `size` bytes
|
// offset = the offset into the receive buffer where to remove `size` bytes
|
||||||
void receive_buffer::cut(int const size, int const packet_size, int const offset)
|
void receive_buffer::cut(int const size, int const packet_size, int const offset)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(packet_size > 0);
|
TORRENT_ASSERT(packet_size > 0);
|
||||||
TORRENT_ASSERT(int(m_recv_buffer.size()) >= size);
|
TORRENT_ASSERT(int(m_recv_buffer.size()) >= size);
|
||||||
TORRENT_ASSERT(int(m_recv_buffer.size()) >= m_recv_pos);
|
TORRENT_ASSERT(int(m_recv_buffer.size()) >= m_recv_pos);
|
||||||
|
@ -136,37 +141,28 @@ buffer::const_interval receive_buffer::get() const
|
||||||
if (m_recv_buffer.empty())
|
if (m_recv_buffer.empty())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_recv_pos == 0);
|
TORRENT_ASSERT(m_recv_pos == 0);
|
||||||
return buffer::interval(nullptr,nullptr);
|
return buffer::const_interval(nullptr,nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rcv_pos = (std::min)(m_recv_pos, int(m_recv_buffer.size()) - m_recv_start);
|
TORRENT_ASSERT(m_recv_start + m_recv_pos <= m_recv_buffer.size());
|
||||||
return buffer::const_interval(&m_recv_buffer[0] + m_recv_start
|
return buffer::const_interval(&m_recv_buffer[0] + m_recv_start
|
||||||
, &m_recv_buffer[0] + m_recv_start + rcv_pos);
|
, &m_recv_buffer[0] + m_recv_start + m_recv_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||||
buffer::interval receive_buffer::mutable_buffer()
|
span<char> receive_buffer::mutable_buffer()
|
||||||
{
|
{
|
||||||
if (m_recv_buffer.empty())
|
INVARIANT_CHECK;
|
||||||
{
|
return span<char>(m_recv_buffer).subspan(m_recv_start, m_recv_pos);
|
||||||
TORRENT_ASSERT(m_recv_pos == 0);
|
|
||||||
return buffer::interval(nullptr,nullptr);
|
|
||||||
}
|
|
||||||
int const rcv_pos = (std::min)(m_recv_pos, int(m_recv_buffer.size()));
|
|
||||||
return buffer::interval(&m_recv_buffer[0] + m_recv_start
|
|
||||||
, &m_recv_buffer[0] + m_recv_start + rcv_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aux::mutable_buffer receive_buffer::mutable_buffer(int const bytes)
|
aux::mutable_buffer receive_buffer::mutable_buffer(int const bytes)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
// bytes is the number of bytes we just received, and m_recv_pos has
|
// bytes is the number of bytes we just received, and m_recv_pos has
|
||||||
// already been adjusted for these bytes. The receive pos immediately
|
// already been adjusted for these bytes. The receive pos immediately
|
||||||
// before we received these bytes was (m_recv_pos - bytes)
|
// before we received these bytes was (m_recv_pos - bytes)
|
||||||
int const last_recv_pos = m_recv_pos - bytes;
|
return span<char>(m_recv_buffer).subspan(m_recv_start + m_recv_pos - bytes, bytes);
|
||||||
TORRENT_ASSERT(bytes <= m_recv_pos);
|
|
||||||
|
|
||||||
return aux::mutable_buffer(&m_recv_buffer[0] + m_recv_start
|
|
||||||
+ last_recv_pos, bytes);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -176,6 +172,7 @@ aux::mutable_buffer receive_buffer::mutable_buffer(int const bytes)
|
||||||
// enough of it lately.
|
// enough of it lately.
|
||||||
void receive_buffer::normalize(int force_shrink)
|
void receive_buffer::normalize(int force_shrink)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(m_recv_end >= m_recv_start);
|
TORRENT_ASSERT(m_recv_end >= m_recv_start);
|
||||||
|
|
||||||
m_watermark.add_sample(std::max(m_recv_end, m_packet_size));
|
m_watermark.add_sample(std::max(m_recv_end, m_packet_size));
|
||||||
|
@ -218,6 +215,7 @@ void receive_buffer::normalize(int force_shrink)
|
||||||
|
|
||||||
void receive_buffer::reset(int packet_size)
|
void receive_buffer::reset(int packet_size)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(m_recv_buffer.size() >= m_recv_end);
|
TORRENT_ASSERT(m_recv_buffer.size() >= m_recv_end);
|
||||||
TORRENT_ASSERT(packet_size > 0);
|
TORRENT_ASSERT(packet_size > 0);
|
||||||
if (m_recv_end > m_packet_size)
|
if (m_recv_end > m_packet_size)
|
||||||
|
|
23
src/upnp.cpp
23
src/upnp.cpp
|
@ -940,8 +940,7 @@ void upnp::on_upnp_xml(error_code const& e
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_state s;
|
parse_state s;
|
||||||
xml_parse(p.get_body().begin, p.get_body().end
|
xml_parse(p.get_body(), std::bind(&find_control_url, _1, _2, _3, boost::ref(s)));
|
||||||
, std::bind(&find_control_url, _1, _2, _3, boost::ref(s)));
|
|
||||||
if (s.control_url.empty())
|
if (s.control_url.empty())
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
@ -1231,14 +1230,14 @@ void upnp::on_upnp_get_ip_address_response(error_code const& e
|
||||||
// </s:Body>
|
// </s:Body>
|
||||||
// </s:Envelope>
|
// </s:Envelope>
|
||||||
|
|
||||||
|
span<char const> body = p.get_body();
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
log("get external IP address response: %s"
|
log("get external IP address response: %s"
|
||||||
, std::string(p.get_body().begin, p.get_body().end).c_str());
|
, std::string(body.data(), body.size()).c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ip_address_parse_state s;
|
ip_address_parse_state s;
|
||||||
xml_parse(const_cast<char*>(p.get_body().begin), const_cast<char*>(p.get_body().end)
|
xml_parse(body, std::bind(&find_ip_address, _1, _2, boost::ref(s)));
|
||||||
, std::bind(&find_ip_address, _1, _2, boost::ref(s)));
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
if (s.error_code != -1)
|
if (s.error_code != -1)
|
||||||
{
|
{
|
||||||
|
@ -1335,9 +1334,8 @@ void upnp::on_upnp_map_response(error_code const& e
|
||||||
// since those might contain valid UPnP error codes
|
// since those might contain valid UPnP error codes
|
||||||
|
|
||||||
error_code_parse_state s;
|
error_code_parse_state s;
|
||||||
xml_parse(const_cast<char*>(p.get_body().begin)
|
span<char const> body = p.get_body();
|
||||||
, const_cast<char*>(p.get_body().end)
|
xml_parse(body, std::bind(&find_error_code, _1, _2, boost::ref(s)));
|
||||||
, std::bind(&find_error_code, _1, _2, boost::ref(s)));
|
|
||||||
|
|
||||||
if (s.error_code != -1)
|
if (s.error_code != -1)
|
||||||
{
|
{
|
||||||
|
@ -1380,7 +1378,7 @@ void upnp::on_upnp_map_response(error_code const& e
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
log("map response: %s"
|
log("map response: %s"
|
||||||
, std::string(p.get_body().begin, p.get_body().end).c_str());
|
, std::string(body.data(), body.size()).c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s.error_code == -1)
|
if (s.error_code == -1)
|
||||||
|
@ -1468,17 +1466,16 @@ void upnp::on_upnp_unmap_response(error_code const& e
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
span<char const> body = p.get_body();
|
||||||
log("unmap response: %s"
|
log("unmap response: %s"
|
||||||
, std::string(p.get_body().begin, p.get_body().end).c_str());
|
, std::string(body.data(), body.size()).c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code_parse_state s;
|
error_code_parse_state s;
|
||||||
if (p.header_finished())
|
if (p.header_finished())
|
||||||
{
|
{
|
||||||
xml_parse(const_cast<char*>(p.get_body().begin)
|
xml_parse(p.get_body(), std::bind(&find_error_code, _1, _2, boost::ref(s)));
|
||||||
, const_cast<char*>(p.get_body().end)
|
|
||||||
, std::bind(&find_error_code, _1, _2, boost::ref(s)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int const proto = m_mappings[mapping].protocol;
|
int const proto = m_mappings[mapping].protocol;
|
||||||
|
|
|
@ -95,10 +95,7 @@ namespace libtorrent { namespace
|
||||||
struct ut_metadata_plugin final
|
struct ut_metadata_plugin final
|
||||||
: torrent_plugin
|
: torrent_plugin
|
||||||
{
|
{
|
||||||
explicit ut_metadata_plugin(torrent& t)
|
explicit ut_metadata_plugin(torrent& t) : m_torrent(t)
|
||||||
: m_torrent(t)
|
|
||||||
// , m_metadata_progress(0)
|
|
||||||
, m_metadata_size(0)
|
|
||||||
{
|
{
|
||||||
// initialize m_metadata_size
|
// initialize m_metadata_size
|
||||||
if (m_torrent.valid_metadata())
|
if (m_torrent.valid_metadata())
|
||||||
|
@ -137,9 +134,9 @@ namespace libtorrent { namespace
|
||||||
return m_metadata_size;
|
return m_metadata_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::const_interval metadata() const
|
span<char const> metadata() const
|
||||||
{
|
{
|
||||||
if (!m_torrent.need_loaded()) return buffer::const_interval(nullptr, nullptr);
|
if (!m_torrent.need_loaded()) return span<char const>();
|
||||||
TORRENT_ASSERT(m_torrent.valid_metadata());
|
TORRENT_ASSERT(m_torrent.valid_metadata());
|
||||||
if (!m_metadata)
|
if (!m_metadata)
|
||||||
{
|
{
|
||||||
|
@ -148,8 +145,7 @@ namespace libtorrent { namespace
|
||||||
TORRENT_ASSERT(hasher(m_metadata.get(), m_metadata_size).final()
|
TORRENT_ASSERT(hasher(m_metadata.get(), m_metadata_size).final()
|
||||||
== m_torrent.torrent_file().info_hash());
|
== m_torrent.torrent_file().info_hash());
|
||||||
}
|
}
|
||||||
return buffer::const_interval(m_metadata.get(), m_metadata.get()
|
return span<char const>(m_metadata.get(), m_metadata_size);
|
||||||
+ m_metadata_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool received_metadata(ut_metadata_peer_plugin& source
|
bool received_metadata(ut_metadata_peer_plugin& source
|
||||||
|
@ -159,16 +155,7 @@ namespace libtorrent { namespace
|
||||||
// we should request.
|
// we should request.
|
||||||
// returns -1 if we should hold off the request
|
// returns -1 if we should hold off the request
|
||||||
int metadata_request(bool has_metadata);
|
int metadata_request(bool has_metadata);
|
||||||
/*
|
|
||||||
// this is called from the peer_connection for
|
|
||||||
// each piece of metadata it receives
|
|
||||||
void metadata_progress(int total_size, int received)
|
|
||||||
{
|
|
||||||
m_metadata_progress += received;
|
|
||||||
m_metadata_size = total_size;
|
|
||||||
m_torrent.set_progress_ppm(std::int64_t(m_metadata_progress) * 1000000 / m_metadata_size);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void on_piece_pass(int) override
|
void on_piece_pass(int) override
|
||||||
{
|
{
|
||||||
// if we became a seed, copy the metadata from
|
// if we became a seed, copy the metadata from
|
||||||
|
@ -194,8 +181,7 @@ namespace libtorrent { namespace
|
||||||
// it is mutable because it's generated lazily
|
// it is mutable because it's generated lazily
|
||||||
mutable boost::shared_array<char> m_metadata;
|
mutable boost::shared_array<char> m_metadata;
|
||||||
|
|
||||||
// int m_metadata_progress;
|
mutable int m_metadata_size = 0;
|
||||||
mutable int m_metadata_size;
|
|
||||||
|
|
||||||
struct metadata_piece
|
struct metadata_piece
|
||||||
{
|
{
|
||||||
|
@ -300,7 +286,7 @@ namespace libtorrent { namespace
|
||||||
// unloaded torrents don't have any metadata. Since we're
|
// unloaded torrents don't have any metadata. Since we're
|
||||||
// about to send the metadata, we need it to be loaded
|
// about to send the metadata, we need it to be loaded
|
||||||
if (!m_tp.need_loaded()) return;
|
if (!m_tp.need_loaded()) return;
|
||||||
metadata = m_tp.metadata().begin + offset;
|
metadata = m_tp.metadata().data() + offset;
|
||||||
metadata_piece_size = (std::min)(
|
metadata_piece_size = (std::min)(
|
||||||
int(m_tp.get_metadata_size() - offset), 16 * 1024);
|
int(m_tp.get_metadata_size() - offset), 16 * 1024);
|
||||||
TORRENT_ASSERT(metadata_piece_size > 0);
|
TORRENT_ASSERT(metadata_piece_size > 0);
|
||||||
|
|
|
@ -37,9 +37,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
TORRENT_EXTRA_EXPORT void xml_parse(char const* p, char const* end
|
TORRENT_EXTRA_EXPORT void xml_parse(span<char const> input
|
||||||
, boost::function<void(int,char const*,int,char const*,int)> callback)
|
, boost::function<void(int,char const*,int,char const*,int)> callback)
|
||||||
{
|
{
|
||||||
|
char const* p = input.data();
|
||||||
|
char const* end = input.data() + input.size();
|
||||||
for(;p != end; ++p)
|
for(;p != end; ++p)
|
||||||
{
|
{
|
||||||
char const* start = p;
|
char const* start = p;
|
||||||
|
|
|
@ -88,7 +88,8 @@ TORRENT_TEST(http_parser)
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(4, 64, false));
|
TEST_CHECK(received == std::make_tuple(4, 64, false));
|
||||||
TEST_CHECK(parser.finished());
|
TEST_CHECK(parser.finished());
|
||||||
TEST_CHECK(std::equal(parser.get_body().begin, parser.get_body().end, "test"));
|
span<char const> body = parser.get_body();
|
||||||
|
TEST_CHECK(std::equal(body.begin(), body.end(), "test"));
|
||||||
TEST_CHECK(parser.header("content-type") == "text/plain");
|
TEST_CHECK(parser.header("content-type") == "text/plain");
|
||||||
TEST_CHECK(atoi(parser.header("content-length").c_str()) == 4);
|
TEST_CHECK(atoi(parser.header("content-length").c_str()) == 4);
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ TORRENT_TEST(http_parser)
|
||||||
received = feed_bytes(parser, upnp_response);
|
received = feed_bytes(parser, upnp_response);
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(0, int(strlen(upnp_response)), false));
|
TEST_CHECK(received == std::make_tuple(0, int(strlen(upnp_response)), false));
|
||||||
TEST_CHECK(parser.get_body().left() == 0);
|
TEST_CHECK(parser.get_body().empty());
|
||||||
TEST_CHECK(parser.header("st") == "upnp:rootdevice");
|
TEST_CHECK(parser.header("st") == "upnp:rootdevice");
|
||||||
TEST_CHECK(parser.header("location")
|
TEST_CHECK(parser.header("location")
|
||||||
== "http://192.168.1.1:5431/dyndev/uuid:000f-66d6-7296000099dc");
|
== "http://192.168.1.1:5431/dyndev/uuid:000f-66d6-7296000099dc");
|
||||||
|
@ -130,7 +131,7 @@ TORRENT_TEST(http_parser)
|
||||||
received = feed_bytes(parser, http1_response);
|
received = feed_bytes(parser, http1_response);
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(0, int(strlen(http1_response)), false));
|
TEST_CHECK(received == std::make_tuple(0, int(strlen(http1_response)), false));
|
||||||
TEST_CHECK(parser.get_body().left() == 0);
|
TEST_CHECK(parser.get_body().empty());
|
||||||
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
||||||
TEST_EQUAL(parser.connection_close(), true);
|
TEST_EQUAL(parser.connection_close(), true);
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ TORRENT_TEST(http_parser)
|
||||||
received = feed_bytes(parser, close_response);
|
received = feed_bytes(parser, close_response);
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(0, int(strlen(close_response)), false));
|
TEST_CHECK(received == std::make_tuple(0, int(strlen(close_response)), false));
|
||||||
TEST_CHECK(parser.get_body().left() == 0);
|
TEST_CHECK(parser.get_body().empty());
|
||||||
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
||||||
TEST_EQUAL(parser.connection_close(), true);
|
TEST_EQUAL(parser.connection_close(), true);
|
||||||
|
|
||||||
|
@ -162,7 +163,7 @@ TORRENT_TEST(http_parser)
|
||||||
received = feed_bytes(parser, keep_alive_response);
|
received = feed_bytes(parser, keep_alive_response);
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(0, int(strlen(keep_alive_response)), false));
|
TEST_CHECK(received == std::make_tuple(0, int(strlen(keep_alive_response)), false));
|
||||||
TEST_CHECK(parser.get_body().left() == 0);
|
TEST_CHECK(parser.get_body().empty());
|
||||||
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
|
||||||
TEST_EQUAL(parser.connection_close(), false);
|
TEST_EQUAL(parser.connection_close(), false);
|
||||||
|
|
||||||
|
@ -226,7 +227,7 @@ TORRENT_TEST(http_parser)
|
||||||
std::printf("payload: %d protocol: %d\n", std::get<0>(received), std::get<1>(received));
|
std::printf("payload: %d protocol: %d\n", std::get<0>(received), std::get<1>(received));
|
||||||
TEST_CHECK(received == std::make_tuple(20, int(strlen(chunked_test)) - 20, false));
|
TEST_CHECK(received == std::make_tuple(20, int(strlen(chunked_test)) - 20, false));
|
||||||
TEST_CHECK(parser.finished());
|
TEST_CHECK(parser.finished());
|
||||||
TEST_CHECK(std::equal(parser.get_body().begin, parser.get_body().end
|
TEST_CHECK(std::equal(parser.get_body().begin(), parser.get_body().end()
|
||||||
, "4\r\ntest\r\n10\r\n0123456789abcdef"));
|
, "4\r\ntest\r\n10\r\n0123456789abcdef"));
|
||||||
TEST_CHECK(parser.header("test-header") == "foobar");
|
TEST_CHECK(parser.header("test-header") == "foobar");
|
||||||
TEST_CHECK(parser.header("content-type") == "text/plain");
|
TEST_CHECK(parser.header("content-type") == "text/plain");
|
||||||
|
@ -249,7 +250,7 @@ TORRENT_TEST(http_parser)
|
||||||
received = feed_bytes(parser, tracker_response);
|
received = feed_bytes(parser, tracker_response);
|
||||||
|
|
||||||
TEST_CHECK(received == std::make_tuple(5, int(strlen(tracker_response) - 5), false));
|
TEST_CHECK(received == std::make_tuple(5, int(strlen(tracker_response) - 5), false));
|
||||||
TEST_CHECK(parser.get_body().left() == 5);
|
TEST_CHECK(parser.get_body().size() == 5);
|
||||||
|
|
||||||
parser.reset();
|
parser.reset();
|
||||||
|
|
||||||
|
@ -469,8 +470,9 @@ TORRENT_TEST(chunked_encoding)
|
||||||
TEST_CHECK(parser.finished());
|
TEST_CHECK(parser.finished());
|
||||||
|
|
||||||
char mutable_buffer[100];
|
char mutable_buffer[100];
|
||||||
memcpy(mutable_buffer, parser.get_body().begin, parser.get_body().left());
|
span<char const> body = parser.get_body();
|
||||||
int len = parser.collapse_chunk_headers(mutable_buffer, parser.get_body().left());
|
memcpy(mutable_buffer, body.begin(), body.size());
|
||||||
|
int const len = parser.collapse_chunk_headers(mutable_buffer, int(body.size()));
|
||||||
|
|
||||||
TEST_CHECK(std::equal(mutable_buffer, mutable_buffer + len, "test12340123456789abcdef"));
|
TEST_CHECK(std::equal(mutable_buffer, mutable_buffer + len, "test12340123456789abcdef"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,11 +264,15 @@ void parser_callback(std::string& out, int token, char const* s, int len
|
||||||
TEST_CHECK(val == nullptr);
|
TEST_CHECK(val == nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
span<char const> str(char const* in)
|
||||||
|
{
|
||||||
|
return span<char const>(in, strlen(in));
|
||||||
|
}
|
||||||
|
|
||||||
void test_parse(char const* in, char const* expected)
|
void test_parse(char const* in, char const* expected)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
xml_parse(in, in + strlen(in), std::bind(&parser_callback
|
xml_parse(str(in), std::bind(&parser_callback
|
||||||
, boost::ref(out), _1, _2, _3, _4, _5));
|
, boost::ref(out), _1, _2, _3, _4, _5));
|
||||||
std::fprintf(stderr, "in: %s\n out: %s\nexpected: %s\n"
|
std::fprintf(stderr, "in: %s\n out: %s\nexpected: %s\n"
|
||||||
, in, out.c_str(), expected);
|
, in, out.c_str(), expected);
|
||||||
|
@ -278,8 +282,7 @@ void test_parse(char const* in, char const* expected)
|
||||||
TORRENT_TEST(upnp_parser1)
|
TORRENT_TEST(upnp_parser1)
|
||||||
{
|
{
|
||||||
parse_state xml_s;
|
parse_state xml_s;
|
||||||
xml_parse(upnp_xml, upnp_xml + sizeof(upnp_xml)
|
xml_parse(upnp_xml, std::bind(&find_control_url, _1, _2, _3, boost::ref(xml_s)));
|
||||||
, std::bind(&find_control_url, _1, _2, _3, boost::ref(xml_s)));
|
|
||||||
|
|
||||||
std::cerr << "namespace " << xml_s.service_type << std::endl;
|
std::cerr << "namespace " << xml_s.service_type << std::endl;
|
||||||
std::cerr << "url_base: " << xml_s.url_base << std::endl;
|
std::cerr << "url_base: " << xml_s.url_base << std::endl;
|
||||||
|
@ -293,8 +296,7 @@ TORRENT_TEST(upnp_parser1)
|
||||||
TORRENT_TEST(upnp_parser2)
|
TORRENT_TEST(upnp_parser2)
|
||||||
{
|
{
|
||||||
parse_state xml_s;
|
parse_state xml_s;
|
||||||
xml_parse(upnp_xml2, upnp_xml2 + sizeof(upnp_xml2)
|
xml_parse(upnp_xml2, std::bind(&find_control_url, _1, _2, _3, boost::ref(xml_s)));
|
||||||
, std::bind(&find_control_url, _1, _2, _3, boost::ref(xml_s)));
|
|
||||||
|
|
||||||
std::cerr << "namespace " << xml_s.service_type << std::endl;
|
std::cerr << "namespace " << xml_s.service_type << std::endl;
|
||||||
std::cerr << "url_base: " << xml_s.url_base << std::endl;
|
std::cerr << "url_base: " << xml_s.url_base << std::endl;
|
||||||
|
|
Loading…
Reference in New Issue