fix file_storage copy constructor (would break python bindings)

This commit is contained in:
Arvid Norberg 2011-06-06 07:47:29 +00:00
parent 57f24128a9
commit f6f516bed0
5 changed files with 79 additions and 12 deletions

View File

@ -77,6 +77,10 @@ namespace libtorrent
struct TORRENT_EXPORT internal_file_entry struct TORRENT_EXPORT internal_file_entry
{ {
friend class file_storage; friend class file_storage;
#ifdef TORRENT_DEBUG
// for torrent_info::invariant_check
friend class torrent_info;
#endif
internal_file_entry() internal_file_entry()
: name(0) : name(0)
, offset(0) , offset(0)

View File

@ -235,6 +235,10 @@ namespace libtorrent
{ {
public: public:
#ifdef TORRENT_DEBUG
void check_invariant() const;
#endif
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
torrent_info(lazy_entry const& torrent_file, int flags = 0); torrent_info(lazy_entry const& torrent_file, int flags = 0);
torrent_info(char const* buffer, int size, int flags = 0); torrent_info(char const* buffer, int size, int flags = 0);
@ -405,7 +409,7 @@ namespace libtorrent
bool is_merkle_torrent() const { return !m_merkle_tree.empty(); } bool is_merkle_torrent() const { return !m_merkle_tree.empty(); }
// if we're logging member offsets, we need access to them // if we're logging member offsets, we need access to them
#if !defined NDEBUG \ #if defined TORRENT_DEBUG \
&& !defined TORRENT_LOGGING \ && !defined TORRENT_LOGGING \
&& !defined TORRENT_VERBOSE_LOGGING \ && !defined TORRENT_VERBOSE_LOGGING \
&& !defined TORRENT_ERROR_LOGGING && !defined TORRENT_ERROR_LOGGING

View File

@ -823,8 +823,9 @@ namespace libtorrent
{ {
m_write_time.add_sample(total_microseconds(done - write_start) / num_write_calls); m_write_time.add_sample(total_microseconds(done - write_start) / num_write_calls);
m_cache_stats.cumulative_write_time += total_milliseconds(done - write_start); m_cache_stats.cumulative_write_time += total_milliseconds(done - write_start);
p.num_contiguous_blocks = contiguous_blocks(p);
} }
if (ret > 0)
p.num_contiguous_blocks = contiguous_blocks(p);
TORRENT_ASSERT(buffer_size == 0); TORRENT_ASSERT(buffer_size == 0);
// std::cerr << " flushing p: " << p.piece << " cached_blocks: " << m_cache_stats.cache_size << std::endl; // std::cerr << " flushing p: " << p.piece << " cached_blocks: " << m_cache_stats.cache_size << std::endl;

View File

@ -109,7 +109,7 @@ namespace libtorrent
, symlink_attribute(fe.symlink_attribute) , symlink_attribute(fe.symlink_attribute)
, path_index(fe.path_index) , path_index(fe.path_index)
{ {
set_name(fe.name, fe.name_len); set_name(fe.filename().c_str());
} }
internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe) internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe)
@ -122,7 +122,7 @@ namespace libtorrent
hidden_attribute = fe.hidden_attribute; hidden_attribute = fe.hidden_attribute;
executable_attribute = fe.executable_attribute; executable_attribute = fe.executable_attribute;
symlink_attribute = fe.symlink_attribute; symlink_attribute = fe.symlink_attribute;
set_name(fe.name, fe.name_len); set_name(fe.filename().c_str());
return *this; return *this;
} }
@ -131,7 +131,7 @@ namespace libtorrent
TORRENT_ASSERT(borrow_chars >= 0); TORRENT_ASSERT(borrow_chars >= 0);
if (borrow_chars > 1023) borrow_chars = 1023; if (borrow_chars > 1023) borrow_chars = 1023;
if (name_len == 0) free((void*)name); if (name_len == 0) free((void*)name);
if (n == 0) if (n == 0 || *n == 0)
{ {
TORRENT_ASSERT(borrow_chars == 0); TORRENT_ASSERT(borrow_chars == 0);
name = 0; name = 0;

View File

@ -63,6 +63,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/file.hpp" #include "libtorrent/file.hpp"
#include "libtorrent/utf8.hpp" #include "libtorrent/utf8.hpp"
#include "libtorrent/time.hpp" #include "libtorrent/time.hpp"
#include "libtorrent/invariant_check.hpp"
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
#include "libtorrent/parse_url.hpp" #include "libtorrent/parse_url.hpp"
@ -474,6 +475,9 @@ namespace libtorrent
, m_private(t.m_private) , m_private(t.m_private)
, m_i2p(t.m_i2p) , m_i2p(t.m_i2p)
{ {
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
t.check_invariant();
#endif
if (m_info_section_size > 0) if (m_info_section_size > 0)
{ {
error_code ec; error_code ec;
@ -483,18 +487,19 @@ namespace libtorrent
+ m_info_section_size, m_info_dict, ec); + m_info_section_size, m_info_dict, ec);
TORRENT_ASSERT(ret == 0); TORRENT_ASSERT(ret == 0);
lazy_entry const* pieces = m_info_dict.dict_find_string("pieces"); ptrdiff_t offset = m_info_section.get() - t.m_info_section.get();
if (pieces && pieces->string_length() == m_files.num_pieces() * 20)
{ m_piece_hashes += offset;
m_piece_hashes = m_info_section.get() + (pieces->string_ptr() - m_info_section.get()); TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get()); TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
}
} }
INVARIANT_CHECK;
} }
void torrent_info::remap_files(file_storage const& f) void torrent_info::remap_files(file_storage const& f)
{ {
INVARIANT_CHECK;
// the new specified file storage must have the exact // the new specified file storage must have the exact
// same size as the current file storage // same size as the current file storage
TORRENT_ASSERT(m_files.total_size() == f.total_size()); TORRENT_ASSERT(m_files.total_size() == f.total_size());
@ -536,6 +541,7 @@ namespace libtorrent
#else #else
parse_torrent_file(e, ec, 0); parse_torrent_file(e, ec, 0);
#endif #endif
INVARIANT_CHECK;
} }
#endif #endif
@ -552,6 +558,8 @@ namespace libtorrent
error_code ec; error_code ec;
if (!parse_torrent_file(torrent_file, ec, flags)) if (!parse_torrent_file(torrent_file, ec, flags))
throw invalid_torrent_file(ec); throw invalid_torrent_file(ec);
INVARIANT_CHECK;
} }
torrent_info::torrent_info(char const* buffer, int size, int flags) torrent_info::torrent_info(char const* buffer, int size, int flags)
@ -570,6 +578,8 @@ namespace libtorrent
if (!parse_torrent_file(e, ec, flags)) if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec); throw invalid_torrent_file(ec);
INVARIANT_CHECK;
} }
torrent_info::torrent_info(std::string const& filename, int flags) torrent_info::torrent_info(std::string const& filename, int flags)
@ -591,6 +601,8 @@ namespace libtorrent
if (!parse_torrent_file(e, ec, flags)) if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec); throw invalid_torrent_file(ec);
INVARIANT_CHECK;
} }
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
@ -616,6 +628,8 @@ namespace libtorrent
if (!parse_torrent_file(e, ec, flags)) if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec); throw invalid_torrent_file(ec);
INVARIANT_CHECK;
} }
#endif #endif
#endif #endif
@ -629,6 +643,8 @@ namespace libtorrent
, m_i2p(false) , m_i2p(false)
{ {
parse_torrent_file(torrent_file, ec, flags); parse_torrent_file(torrent_file, ec, flags);
INVARIANT_CHECK;
} }
torrent_info::torrent_info(char const* buffer, int size, error_code& ec, int flags) torrent_info::torrent_info(char const* buffer, int size, error_code& ec, int flags)
@ -644,6 +660,8 @@ namespace libtorrent
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0) if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
return; return;
parse_torrent_file(e, ec, flags); parse_torrent_file(e, ec, flags);
INVARIANT_CHECK;
} }
torrent_info::torrent_info(std::string const& filename, error_code& ec, int flags) torrent_info::torrent_info(std::string const& filename, error_code& ec, int flags)
@ -663,6 +681,8 @@ namespace libtorrent
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0) if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
return; return;
parse_torrent_file(e, ec, flags); parse_torrent_file(e, ec, flags);
INVARIANT_CHECK;
} }
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
@ -685,6 +705,8 @@ namespace libtorrent
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0) if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
return; return;
parse_torrent_file(e, ec, flags); parse_torrent_file(e, ec, flags);
INVARIANT_CHECK;
} }
#endif #endif
@ -708,6 +730,8 @@ namespace libtorrent
void torrent_info::copy_on_write() void torrent_info::copy_on_write()
{ {
INVARIANT_CHECK;
if (m_orig_files) return; if (m_orig_files) return;
m_orig_files.reset(new file_storage(m_files)); m_orig_files.reset(new file_storage(m_files));
} }
@ -719,6 +743,8 @@ namespace libtorrent
void torrent_info::swap(torrent_info& ti) void torrent_info::swap(torrent_info& ti)
{ {
INVARIANT_CHECK;
using std::swap; using std::swap;
m_urls.swap(ti.m_urls); m_urls.swap(ti.m_urls);
m_web_seeds.swap(ti.m_web_seeds); m_web_seeds.swap(ti.m_web_seeds);
@ -912,6 +938,8 @@ namespace libtorrent
bool torrent_info::add_merkle_nodes(std::map<int, sha1_hash> const& subtree bool torrent_info::add_merkle_nodes(std::map<int, sha1_hash> const& subtree
, int piece) , int piece)
{ {
INVARIANT_CHECK;
int n = m_merkle_first_leaf + piece; int n = m_merkle_first_leaf + piece;
typedef std::map<int, sha1_hash>::const_iterator iter; typedef std::map<int, sha1_hash>::const_iterator iter;
iter i = subtree.find(n); iter i = subtree.find(n);
@ -962,6 +990,8 @@ namespace libtorrent
// the given piece // the given piece
std::map<int, sha1_hash> torrent_info::build_merkle_list(int piece) const std::map<int, sha1_hash> torrent_info::build_merkle_list(int piece) const
{ {
INVARIANT_CHECK;
std::map<int, sha1_hash> ret; std::map<int, sha1_hash> ret;
int n = m_merkle_first_leaf + piece; int n = m_merkle_first_leaf + piece;
ret[n] = m_merkle_tree[n]; ret[n] = m_merkle_tree[n];
@ -1203,6 +1233,8 @@ namespace libtorrent
void torrent_info::print(std::ostream& os) const void torrent_info::print(std::ostream& os) const
{ {
INVARIANT_CHECK;
os << "trackers:\n"; os << "trackers:\n";
for (std::vector<announce_entry>::const_iterator i = trackers().begin(); for (std::vector<announce_entry>::const_iterator i = trackers().begin();
i != trackers().end(); ++i) i != trackers().end(); ++i)
@ -1222,5 +1254,31 @@ namespace libtorrent
// ------- end deprecation ------- // ------- end deprecation -------
#endif #endif
#ifdef TORRENT_DEBUG
void torrent_info::check_invariant() const
{
for (file_storage::iterator i = m_files.begin()
, end(m_files.end()); i != end; ++i)
{
TORRENT_ASSERT(i->name != 0);
if (i->name_len > 0)
{
// name needs to point into the allocated info section buffer
TORRENT_ASSERT(i->name >= m_info_section.get());
TORRENT_ASSERT(i->name < m_info_section.get() + m_info_section_size);
}
else
{
// name must be a valid string
TORRENT_ASSERT(strlen(i->name) < 2048);
}
}
TORRENT_ASSERT(m_piece_hashes);
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
}
#endif
} }