fixed torrent_info copy constructor. restricted copying of lazy_entry. Fixed build. added pascal_string type to be used with lazy_entry (trunk only)
This commit is contained in:
parent
8dd244581d
commit
a80b2b0fce
|
@ -90,6 +90,8 @@ namespace libtorrent
|
|||
attribute_symlink = 8
|
||||
};
|
||||
|
||||
void reserve(int num_files);
|
||||
|
||||
void add_file(file_entry const& e);
|
||||
void add_file(std::string const& p, size_type size, int flags = 0
|
||||
, std::time_t mtime = 0, std::string const& s_p = "");
|
||||
|
|
|
@ -145,6 +145,7 @@ namespace libtorrent
|
|||
{ return const_cast<lazy_entry*>(this)->dict_find(name); }
|
||||
|
||||
std::string dict_find_string_value(char const* name) const;
|
||||
pascal_string dict_find_pstr(char const* name) const;
|
||||
size_type dict_find_int_value(char const* name, size_type default_val = 0) const;
|
||||
lazy_entry const* dict_find_dict(char const* name) const;
|
||||
lazy_entry const* dict_find_list(char const* name) const;
|
||||
|
@ -187,6 +188,7 @@ namespace libtorrent
|
|||
{ return const_cast<lazy_entry*>(this)->list_at(i); }
|
||||
|
||||
std::string list_string_value_at(int i) const;
|
||||
pascal_string list_pstr_at(int i) const;
|
||||
size_type list_int_value_at(int i, size_type default_val = 0) const;
|
||||
|
||||
int list_size() const
|
||||
|
|
|
@ -173,6 +173,7 @@ namespace libtorrent
|
|||
#endif // TORRENT_USE_WSTRING
|
||||
#endif
|
||||
|
||||
torrent_info(torrent_info const& t);
|
||||
torrent_info(sha1_hash const& info_hash);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec);
|
||||
torrent_info(char const* buffer, int size, error_code& ec);
|
||||
|
@ -320,6 +321,9 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
// not assignable
|
||||
torrent_info const& operator=(torrent_info const&);
|
||||
|
||||
void copy_on_write();
|
||||
bool parse_torrent_file(lazy_entry const& libtorrent, error_code& ec);
|
||||
|
||||
|
|
|
@ -46,6 +46,11 @@ namespace libtorrent
|
|||
, m_num_pieces(0)
|
||||
{}
|
||||
|
||||
void file_storage::reserve(int num_files)
|
||||
{
|
||||
m_files.reserve(num_files);
|
||||
}
|
||||
|
||||
int file_storage::piece_size(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < num_pieces());
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace libtorrent
|
|||
{
|
||||
int fail_bdecode(lazy_entry& ret)
|
||||
{
|
||||
ret = lazy_entry();
|
||||
ret.clear();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,13 @@ namespace libtorrent
|
|||
return e->string_value();
|
||||
}
|
||||
|
||||
pascal_string lazy_entry::dict_find_pstr(char const* name) const
|
||||
{
|
||||
lazy_entry const* e = dict_find(name);
|
||||
if (e == 0 || e->type() != lazy_entry::string_t) return pascal_string(0, 0);
|
||||
return e->string_pstr();
|
||||
}
|
||||
|
||||
lazy_entry const* lazy_entry::dict_find_string(char const* name) const
|
||||
{
|
||||
lazy_entry const* e = dict_find(name);
|
||||
|
@ -338,6 +345,13 @@ namespace libtorrent
|
|||
return e->string_value();
|
||||
}
|
||||
|
||||
pascal_string lazy_entry::list_pstr_at(int i) const
|
||||
{
|
||||
lazy_entry const* e = list_at(i);
|
||||
if (e == 0 || e->type() != lazy_entry::string_t) return pascal_string(0, 0);
|
||||
return e->string_pstr();
|
||||
}
|
||||
|
||||
size_type lazy_entry::list_int_value_at(int i, size_type default_val) const
|
||||
{
|
||||
lazy_entry const* e = list_at(i);
|
||||
|
|
|
@ -303,14 +303,24 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
struct pascal_string
|
||||
struct string_less_no_case
|
||||
{
|
||||
int len;
|
||||
char const* ptr;
|
||||
bool operator<(pascal_string const& rhs) const
|
||||
bool operator()(std::string const& lhs, std::string const& rhs)
|
||||
{
|
||||
return memcmp(ptr, rhs.ptr, (std::min)(len, rhs.len)) < 0
|
||||
|| len < rhs.len;
|
||||
char c1, c2;
|
||||
char const* s1 = lhs.c_str();
|
||||
char const* s2 = rhs.c_str();
|
||||
|
||||
while (*s1 != 0 && *s2 != 0)
|
||||
{
|
||||
c1 = to_lower(*s1);
|
||||
c2 = to_lower(*s2);
|
||||
if (c1 < c2) return true;
|
||||
if (c1 > c2) return false;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -318,29 +328,23 @@ namespace libtorrent
|
|||
, std::string const& root_dir)
|
||||
{
|
||||
if (list.type() != lazy_entry::list_t) return false;
|
||||
target.reserve(list.list_size());
|
||||
for (int i = 0, end(list.list_size()); i < end; ++i)
|
||||
{
|
||||
file_entry e;
|
||||
if (!extract_single_file(*list.list_at(i), e, root_dir))
|
||||
return false;
|
||||
int cnt = 0;
|
||||
std::set<pascal_string> files;
|
||||
pascal_string =
|
||||
while (!files.insert(path).second)
|
||||
for (file_storage::iterator k = target.begin()
|
||||
, end(target.end()); k != end; ++k)
|
||||
std::set<std::string, string_less_no_case> files;
|
||||
|
||||
// as long as we this file already exists
|
||||
// increase the counter
|
||||
while (!files.insert(e.path).second)
|
||||
{
|
||||
if (string_equal_no_case(e.path.c_str()
|
||||
, k->path.c_str())) ++cnt;
|
||||
}
|
||||
if (cnt)
|
||||
{
|
||||
char suffix[15];
|
||||
snprintf(suffix, sizeof(suffix), ".%d", cnt);
|
||||
replace_extension(e.path, suffix + extension(e.path));
|
||||
// TODO: we should really make sure that this new name
|
||||
// doesn't already exist as well, otherwise we might
|
||||
// just create another collision
|
||||
++cnt;
|
||||
char suffix[50];
|
||||
snprintf(suffix, sizeof(suffix), ".%d%s", cnt, extension(e.path).c_str());
|
||||
replace_extension(e.path, suffix);
|
||||
}
|
||||
target.add_file(e);
|
||||
}
|
||||
|
@ -403,6 +407,42 @@ namespace libtorrent
|
|||
updating = false;
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(torrent_info const& t)
|
||||
: m_files(t.m_files)
|
||||
, m_orig_files(t.m_orig_files)
|
||||
, m_urls(t.m_urls)
|
||||
, m_url_seeds(t.m_url_seeds)
|
||||
, m_http_seeds(t.m_http_seeds)
|
||||
, m_nodes(t.m_nodes)
|
||||
, m_info_hash(t.m_info_hash)
|
||||
, m_creation_date(t.m_creation_date)
|
||||
, m_comment(t.m_comment)
|
||||
, m_created_by(t.m_created_by)
|
||||
, m_multifile(t.m_multifile)
|
||||
, m_private(t.m_private)
|
||||
, m_i2p(t.m_i2p)
|
||||
, m_info_section_size(t.m_info_section_size)
|
||||
, m_piece_hashes(t.m_piece_hashes)
|
||||
, m_merkle_tree(t.m_merkle_tree)
|
||||
, m_merkle_first_leaf(t.m_merkle_first_leaf)
|
||||
{
|
||||
if (m_info_section_size > 0)
|
||||
{
|
||||
m_info_section.reset(new char[m_info_section_size]);
|
||||
memcpy(m_info_section.get(), t.m_info_section.get(), m_info_section_size);
|
||||
int ret = lazy_bdecode(m_info_section.get(), m_info_section.get()
|
||||
+ m_info_section_size, m_info_dict);
|
||||
|
||||
lazy_entry const* pieces = m_info_dict.dict_find_string("pieces");
|
||||
if (pieces && pieces->string_length() == m_files.num_pieces() * 20)
|
||||
{
|
||||
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() + m_info_section_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
// standard constructor that parses a torrent file
|
||||
torrent_info::torrent_info(entry const& torrent_file)
|
||||
|
@ -638,7 +678,9 @@ namespace libtorrent
|
|||
swap(m_info_section, ti.m_info_section);
|
||||
swap(m_info_section_size, ti.m_info_section_size);
|
||||
swap(m_piece_hashes, ti.m_piece_hashes);
|
||||
swap(m_info_dict, ti.m_info_dict);
|
||||
m_info_dict.swap(ti.m_info_dict);
|
||||
swap(m_merkle_tree, ti.m_merkle_tree);
|
||||
swap(m_merkle_first_leaf, ti.m_merkle_first_leaf);
|
||||
}
|
||||
|
||||
bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec)
|
||||
|
|
Loading…
Reference in New Issue