forked from premiere/premiere-libtorrent
handle torrents with duplicate filenames
This commit is contained in:
parent
356db54dce
commit
10eb3fa00f
|
@ -1,3 +1,4 @@
|
||||||
|
* handle torrents with duplicate filenames
|
||||||
* piece timeouts are adjusted to download rate limits
|
* piece timeouts are adjusted to download rate limits
|
||||||
* encodes urls in torrent files that needs to be encoded
|
* encodes urls in torrent files that needs to be encoded
|
||||||
* fixed not passing &supportcrypto=1 when encryption is disabled
|
* fixed not passing &supportcrypto=1 when encryption is disabled
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace libtorrent
|
||||||
char TORRENT_EXPORT to_lower(char c);
|
char TORRENT_EXPORT to_lower(char c);
|
||||||
|
|
||||||
bool TORRENT_EXPORT string_begins_no_case(char const* s1, char const* s2);
|
bool TORRENT_EXPORT string_begins_no_case(char const* s1, char const* s2);
|
||||||
|
bool TORRENT_EXPORT string_equal_no_case(char const* s1, char const* s2);
|
||||||
|
|
||||||
std::string TORRENT_EXPORT unescape_string(std::string const& s, error_code& ec);
|
std::string TORRENT_EXPORT unescape_string(std::string const& s, error_code& ec);
|
||||||
// replaces all disallowed URL characters by their %-encoding
|
// replaces all disallowed URL characters by their %-encoding
|
||||||
|
|
|
@ -111,6 +111,17 @@ namespace libtorrent
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool string_equal_no_case(char const* s1, char const* s2)
|
||||||
|
{
|
||||||
|
while (to_lower(*s1) == to_lower(*s2))
|
||||||
|
{
|
||||||
|
if (*s1 == 0) return true;
|
||||||
|
++s1;
|
||||||
|
++s2;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string unescape_string(std::string const& s, error_code& ec)
|
std::string unescape_string(std::string const& s, error_code& ec)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
|
@ -278,6 +278,22 @@ namespace libtorrent
|
||||||
file_entry e;
|
file_entry e;
|
||||||
if (!extract_single_file(*list.list_at(i), e, root_dir))
|
if (!extract_single_file(*list.list_at(i), e, root_dir))
|
||||||
return false;
|
return false;
|
||||||
|
int cnt = 0;
|
||||||
|
for (file_storage::iterator k = target.begin()
|
||||||
|
, end(target.end()); k != end; ++k)
|
||||||
|
{
|
||||||
|
if (string_equal_no_case(e.path.string().c_str()
|
||||||
|
, k->path.string().c_str())) ++cnt;
|
||||||
|
}
|
||||||
|
if (cnt)
|
||||||
|
{
|
||||||
|
char suffix[15];
|
||||||
|
snprintf(suffix, sizeof(suffix), ".%d", cnt);
|
||||||
|
e.path.replace_extension(suffix + e.path.extension());
|
||||||
|
// TODO: we should really make sure that this new name
|
||||||
|
// doesn't already exist as well, otherwise we might
|
||||||
|
// just create another collision
|
||||||
|
}
|
||||||
target.add_file(e);
|
target.add_file(e);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
17
src/upnp.cpp
17
src/upnp.cpp
|
@ -746,17 +746,6 @@ namespace
|
||||||
dst.clear();
|
dst.clear();
|
||||||
while (*src) dst.push_back(to_lower(*src++));
|
while (*src) dst.push_back(to_lower(*src++));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string_equal_nocase(char const* lhs, char const* rhs)
|
|
||||||
{
|
|
||||||
while (to_lower(*lhs) == to_lower(*rhs))
|
|
||||||
{
|
|
||||||
if (*lhs == 0) return true;
|
|
||||||
++lhs;
|
|
||||||
++rhs;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct parse_state
|
struct parse_state
|
||||||
|
@ -781,10 +770,10 @@ struct parse_state
|
||||||
{
|
{
|
||||||
std::list<std::string>::reverse_iterator i = tag_stack.rbegin();
|
std::list<std::string>::reverse_iterator i = tag_stack.rbegin();
|
||||||
if (i == tag_stack.rend()) return false;
|
if (i == tag_stack.rend()) return false;
|
||||||
if (!string_equal_nocase(i->c_str(), str2)) return false;
|
if (!string_equal_no_case(i->c_str(), str2)) return false;
|
||||||
++i;
|
++i;
|
||||||
if (i == tag_stack.rend()) return false;
|
if (i == tag_stack.rend()) return false;
|
||||||
if (!string_equal_nocase(i->c_str(), str1)) return false;
|
if (!string_equal_no_case(i->c_str(), str1)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -814,7 +803,7 @@ void find_control_url(int type, char const* string, parse_state& state)
|
||||||
// std::cout << " " << string << std::endl;
|
// std::cout << " " << string << std::endl;
|
||||||
if (!state.in_service && state.top_tags("service", "servicetype"))
|
if (!state.in_service && state.top_tags("service", "servicetype"))
|
||||||
{
|
{
|
||||||
if (string_equal_nocase(string, state.service_type))
|
if (string_equal_no_case(string, state.service_type))
|
||||||
state.in_service = true;
|
state.in_service = true;
|
||||||
}
|
}
|
||||||
else if (state.in_service && state.top_tags("service", "controlurl"))
|
else if (state.in_service && state.top_tags("service", "controlurl"))
|
||||||
|
|
|
@ -423,6 +423,13 @@ int test_main()
|
||||||
TEST_CHECK(to_lower('-') == '-');
|
TEST_CHECK(to_lower('-') == '-');
|
||||||
TEST_CHECK(to_lower('&') == '&');
|
TEST_CHECK(to_lower('&') == '&');
|
||||||
|
|
||||||
|
// test string_equal_no_case
|
||||||
|
|
||||||
|
TEST_CHECK(string_equal_no_case("foobar", "FoobAR"));
|
||||||
|
TEST_CHECK(string_equal_no_case("foobar", "foobar"));
|
||||||
|
TEST_CHECK(!string_equal_no_case("foobar", "foobar "));
|
||||||
|
TEST_CHECK(!string_equal_no_case("foobar", "F00"));
|
||||||
|
|
||||||
// test string_begins_no_case
|
// test string_begins_no_case
|
||||||
|
|
||||||
TEST_CHECK(string_begins_no_case("foobar", "FoobAR --"));
|
TEST_CHECK(string_begins_no_case("foobar", "FoobAR --"));
|
||||||
|
|
Loading…
Reference in New Issue