improve duplicate file detection in torrent files
This commit is contained in:
parent
31ecd1b914
commit
bcb703b9a3
|
@ -133,6 +133,7 @@ namespace libtorrent
|
|||
TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f);
|
||||
TORRENT_EXTRA_EXPORT char const* next_path_element(char const* p);
|
||||
TORRENT_EXTRA_EXPORT std::string extension(std::string const& f);
|
||||
TORRENT_EXTRA_EXPORT std::string remove_extension(std::string const& f);
|
||||
TORRENT_EXTRA_EXPORT void replace_extension(std::string& f, std::string const& ext);
|
||||
TORRENT_EXTRA_EXPORT bool is_root_path(std::string const& f);
|
||||
|
||||
|
|
12
src/file.cpp
12
src/file.cpp
|
@ -423,6 +423,18 @@ namespace libtorrent
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string remove_extension(std::string const& f)
|
||||
{
|
||||
char const* slash = strrchr(f.c_str(), '/');
|
||||
#ifdef TORRENT_WINDOWS
|
||||
slash = (std::max)((char const*)strrchr(f.c_str(), '\\'), slash);
|
||||
#endif
|
||||
char const* ext = strrchr(f.c_str(), '.');
|
||||
// if we don't have an extension, just return f
|
||||
if (ext == 0 || ext == &f[0] || (slash != NULL && ext < slash)) return f;
|
||||
return f.substr(0, ext - &f[0]);
|
||||
}
|
||||
|
||||
void replace_extension(std::string& f, std::string const& ext)
|
||||
{
|
||||
for (int i = f.size() - 1; i >= 0; --i)
|
||||
|
|
|
@ -402,12 +402,17 @@ namespace libtorrent
|
|||
// as long as this file already exists
|
||||
// increase the counter
|
||||
int cnt = 0;
|
||||
while (!files.insert(e.path).second)
|
||||
if (!files.insert(e.path).second)
|
||||
{
|
||||
++cnt;
|
||||
char suffix[50];
|
||||
snprintf(suffix, sizeof(suffix), "%d%s", cnt, extension(e.path).c_str());
|
||||
replace_extension(e.path, suffix);
|
||||
std::string base = remove_extension(e.path);
|
||||
std::string ext = extension(e.path);
|
||||
do
|
||||
{
|
||||
++cnt;
|
||||
char new_ext[50];
|
||||
snprintf(new_ext, sizeof(new_ext), ".%d%s", cnt, ext.c_str());
|
||||
e.path = base + new_ext;
|
||||
} while (!files.insert(e.path).second);
|
||||
}
|
||||
target.add_file(e, file_hash ? file_hash->string_ptr() + info_ptr_diff : 0);
|
||||
|
||||
|
|
|
@ -127,6 +127,11 @@ int test_main()
|
|||
TEST_EQUAL(extension("blah.foo."), ".");
|
||||
TEST_EQUAL(extension("blah.foo/bar"), "");
|
||||
|
||||
TEST_EQUAL(remove_extension("blah"), "blah");
|
||||
TEST_EQUAL(remove_extension("blah.exe"), "blah");
|
||||
TEST_EQUAL(remove_extension("blah.foo.bar"), "blah.foo");
|
||||
TEST_EQUAL(remove_extension("blah.foo."), "blah.foo");
|
||||
|
||||
TEST_EQUAL(filename("blah"), "blah");
|
||||
TEST_EQUAL(filename("/blah/foo/bar"), "bar");
|
||||
TEST_EQUAL(filename("/blah/foo/bar/"), "bar");
|
||||
|
|
|
@ -41,7 +41,6 @@ int test_main()
|
|||
{
|
||||
|
||||
file_storage fs;
|
||||
int total_size = 100 * 0x4000;
|
||||
|
||||
fs.add_file("test/temporary.txt", 0x4000);
|
||||
fs.add_file("test/A/tmp", 0x4000);
|
||||
|
@ -76,12 +75,17 @@ int test_main()
|
|||
"test/A/tmp",
|
||||
"test/Temporary.1.txt", // duplicate of temporary.txt
|
||||
"test/TeMPorArY.2.txT", // duplicate of temporary.txt
|
||||
"test/a.1", // a file may not have the same name as a directory
|
||||
|
||||
// a file may not have the same name as a directory
|
||||
// however, detecting this is not supported currently.
|
||||
// it is in the next major release
|
||||
"test/a",
|
||||
|
||||
"test/b.exe",
|
||||
"test/B.1.ExE", // duplicate of b.exe
|
||||
"test/B.2.exe", // duplicate of b.exe
|
||||
"test/test/TEMPORARY.TXT", // a file with the same name in a seprate directory is fine
|
||||
"test/A.2", // duplicate of directory a
|
||||
"test/A.1", // duplicate of directory a
|
||||
};
|
||||
|
||||
for (int i = 0; i < ti.num_files(); ++i)
|
||||
|
|
Loading…
Reference in New Issue