fix set_naem() on file_storage actually affecting save paths
This commit is contained in:
parent
8f2683fe5d
commit
25e53cd799
|
@ -25,6 +25,7 @@
|
||||||
* fix uTP edge case where udp socket buffer fills up
|
* fix uTP edge case where udp socket buffer fills up
|
||||||
* fix nagle implementation in uTP
|
* fix nagle implementation in uTP
|
||||||
|
|
||||||
|
* fix set_naem() on file_storage actually affecting save paths
|
||||||
* fix large file support issue on mingw
|
* fix large file support issue on mingw
|
||||||
* add some error handling to set_piece_hashes()
|
* add some error handling to set_piece_hashes()
|
||||||
* fix completed-on timestamp to not be clobbered on each startup
|
* fix completed-on timestamp to not be clobbered on each startup
|
||||||
|
|
|
@ -121,26 +121,28 @@ namespace libtorrent
|
||||||
internal_file_entry()
|
internal_file_entry()
|
||||||
: name(NULL)
|
: name(NULL)
|
||||||
, offset(0)
|
, offset(0)
|
||||||
, symlink_index(not_a_symlink)
|
|
||||||
, size(0)
|
, size(0)
|
||||||
|
, symlink_index(not_a_symlink)
|
||||||
, name_len(name_is_owned)
|
, name_len(name_is_owned)
|
||||||
, pad_file(false)
|
, pad_file(false)
|
||||||
, hidden_attribute(false)
|
, hidden_attribute(false)
|
||||||
, executable_attribute(false)
|
, executable_attribute(false)
|
||||||
, symlink_attribute(false)
|
, symlink_attribute(false)
|
||||||
|
, no_root_dir(false)
|
||||||
, path_index(-1)
|
, path_index(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
internal_file_entry(file_entry const& e)
|
internal_file_entry(file_entry const& e)
|
||||||
: name(NULL)
|
: name(NULL)
|
||||||
, offset(e.offset)
|
, offset(e.offset)
|
||||||
, symlink_index(not_a_symlink)
|
|
||||||
, size(e.size)
|
, size(e.size)
|
||||||
|
, symlink_index(not_a_symlink)
|
||||||
, name_len(name_is_owned)
|
, name_len(name_is_owned)
|
||||||
, pad_file(e.pad_file)
|
, pad_file(e.pad_file)
|
||||||
, hidden_attribute(e.hidden_attribute)
|
, hidden_attribute(e.hidden_attribute)
|
||||||
, executable_attribute(e.executable_attribute)
|
, executable_attribute(e.executable_attribute)
|
||||||
, symlink_attribute(e.symlink_attribute)
|
, symlink_attribute(e.symlink_attribute)
|
||||||
|
, no_root_dir(false)
|
||||||
, path_index(-1)
|
, path_index(-1)
|
||||||
{
|
{
|
||||||
set_name(e.path.c_str());
|
set_name(e.path.c_str());
|
||||||
|
@ -167,18 +169,18 @@ namespace libtorrent
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
name_is_owned = (1<<12)-1,
|
name_is_owned = (1<<12)-1,
|
||||||
not_a_symlink = (1<<16)-1
|
not_a_symlink = (1<<15)-1
|
||||||
};
|
};
|
||||||
// the offset of this file inside the torrent
|
// the offset of this file inside the torrent
|
||||||
boost::uint64_t offset:48;
|
boost::uint64_t offset:48;
|
||||||
|
|
||||||
// index into file_storage::m_symlinks or not_a_symlink
|
|
||||||
// if this is not a symlink
|
|
||||||
boost::uint64_t symlink_index:16;
|
|
||||||
|
|
||||||
// the size of this file
|
// the size of this file
|
||||||
boost::uint64_t size:48;
|
boost::uint64_t size:48;
|
||||||
|
|
||||||
|
// index into file_storage::m_symlinks or not_a_symlink
|
||||||
|
// if this is not a symlink
|
||||||
|
boost::uint64_t symlink_index:15;
|
||||||
|
|
||||||
// the number of characters in the name. If this is
|
// the number of characters in the name. If this is
|
||||||
// name_is_owned, name is null terminated and owned by this object
|
// name_is_owned, name is null terminated and owned by this object
|
||||||
// (i.e. it should be freed in the destructor). If
|
// (i.e. it should be freed in the destructor). If
|
||||||
|
@ -189,14 +191,20 @@ namespace libtorrent
|
||||||
boost::uint64_t hidden_attribute:1;
|
boost::uint64_t hidden_attribute:1;
|
||||||
boost::uint64_t executable_attribute:1;
|
boost::uint64_t executable_attribute:1;
|
||||||
boost::uint64_t symlink_attribute:1;
|
boost::uint64_t symlink_attribute:1;
|
||||||
|
|
||||||
|
// if this is true, don't include m_name as part of the
|
||||||
|
// path to this file
|
||||||
|
boost::uint64_t no_root_dir:1;
|
||||||
|
|
||||||
// the index into file_storage::m_paths. To get
|
// the index into file_storage::m_paths. To get
|
||||||
// the full path to this file, concatenate the path
|
// the full path to this file, concatenate the path
|
||||||
// from that array with the 'name' field in
|
// from that array with the 'name' field in
|
||||||
// this struct
|
// this struct
|
||||||
// if path_index == -2, it means the filename
|
// values for path_index include:
|
||||||
|
// -1 means no path (i.e. single file torrent)
|
||||||
|
// -2, it means the filename
|
||||||
// in this field contains the full, absolute path
|
// in this field contains the full, absolute path
|
||||||
// to the file
|
// to the file
|
||||||
// -1 means no path (i.e. single file torrent)
|
|
||||||
int path_index;
|
int path_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -527,7 +535,10 @@ namespace libtorrent
|
||||||
std::vector<size_type> m_file_base;
|
std::vector<size_type> m_file_base;
|
||||||
|
|
||||||
// all unique paths files have. The internal_file_entry::path_index
|
// all unique paths files have. The internal_file_entry::path_index
|
||||||
// points into this array
|
// points into this array. The paths don't include the root directory
|
||||||
|
// name for multi-file torrents. The m_name field need to be
|
||||||
|
// prepended to these paths, and the filename of a specific file
|
||||||
|
// entry appended, to form full file paths
|
||||||
std::vector<std::string> m_paths;
|
std::vector<std::string> m_paths;
|
||||||
|
|
||||||
// name of torrent. For multi-file torrents
|
// name of torrent. For multi-file torrents
|
||||||
|
|
|
@ -78,29 +78,47 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string parent = parent_path(fname);
|
std::string parent = parent_path(fname);
|
||||||
|
|
||||||
if (parent.empty())
|
if (parent.empty())
|
||||||
{
|
{
|
||||||
e.path_index = -1;
|
e.path_index = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent.size() >= m_name.size()
|
||||||
|
&& parent.compare(0, m_name.size(), m_name) == 0
|
||||||
|
&& (parent.size() == m_name.size()
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
|| parent[m_name.size()] == '\\'
|
||||||
|
#endif
|
||||||
|
|| parent[m_name.size()] == '/'
|
||||||
|
))
|
||||||
|
{
|
||||||
|
parent.erase(parent.begin(), parent.begin() + m_name.size()
|
||||||
|
+ (m_name.size() == parent.size()?0:1));
|
||||||
|
e.no_root_dir = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// do we already have this path in the path list?
|
e.no_root_dir = true;
|
||||||
std::vector<std::string>::reverse_iterator p
|
|
||||||
= std::find(m_paths.rbegin(), m_paths.rend(), parent);
|
|
||||||
|
|
||||||
if (p == m_paths.rend())
|
|
||||||
{
|
|
||||||
// no, we don't. add it
|
|
||||||
e.path_index = m_paths.size();
|
|
||||||
m_paths.push_back(parent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// yes we do. use it
|
|
||||||
e.path_index = p.base() - m_paths.begin() - 1;
|
|
||||||
}
|
|
||||||
e.set_name(filename(e.filename()).c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do we already have this path in the path list?
|
||||||
|
std::vector<std::string>::reverse_iterator p
|
||||||
|
= std::find(m_paths.rbegin(), m_paths.rend(), parent);
|
||||||
|
|
||||||
|
if (p == m_paths.rend())
|
||||||
|
{
|
||||||
|
// no, we don't. add it
|
||||||
|
e.path_index = m_paths.size();
|
||||||
|
m_paths.push_back(parent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// yes we do. use it
|
||||||
|
e.path_index = p.base() - m_paths.begin() - 1;
|
||||||
|
}
|
||||||
|
e.set_name(filename(e.filename()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
file_entry::file_entry(): offset(0), size(0), file_base(0)
|
file_entry::file_entry(): offset(0), size(0), file_base(0)
|
||||||
|
@ -111,7 +129,10 @@ namespace libtorrent
|
||||||
|
|
||||||
file_entry::~file_entry() {}
|
file_entry::~file_entry() {}
|
||||||
|
|
||||||
internal_file_entry::~internal_file_entry() { if (name_len == name_is_owned) free((void*)name); }
|
internal_file_entry::~internal_file_entry()
|
||||||
|
{
|
||||||
|
if (name_len == name_is_owned) free((void*)name);
|
||||||
|
}
|
||||||
|
|
||||||
internal_file_entry::internal_file_entry(internal_file_entry const& fe)
|
internal_file_entry::internal_file_entry(internal_file_entry const& fe)
|
||||||
: name(0)
|
: name(0)
|
||||||
|
@ -123,6 +144,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)
|
||||||
|
, no_root_dir(fe.no_root_dir)
|
||||||
, path_index(fe.path_index)
|
, path_index(fe.path_index)
|
||||||
{
|
{
|
||||||
set_name(fe.filename().c_str());
|
set_name(fe.filename().c_str());
|
||||||
|
@ -138,6 +160,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;
|
||||||
|
no_root_dir = fe.no_root_dir;
|
||||||
set_name(fe.filename().c_str());
|
set_name(fe.filename().c_str());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +355,8 @@ namespace libtorrent
|
||||||
ret.hidden_attribute = ife.hidden_attribute;
|
ret.hidden_attribute = ife.hidden_attribute;
|
||||||
ret.executable_attribute = ife.executable_attribute;
|
ret.executable_attribute = ife.executable_attribute;
|
||||||
ret.symlink_attribute = ife.symlink_attribute;
|
ret.symlink_attribute = ife.symlink_attribute;
|
||||||
if (ife.symlink_index != internal_file_entry::not_a_symlink) ret.symlink_path = symlink(index);
|
if (ife.symlink_index != internal_file_entry::not_a_symlink)
|
||||||
|
ret.symlink_path = symlink(index);
|
||||||
ret.filehash = hash(index);
|
ret.filehash = hash(index);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -494,14 +518,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
||||||
internal_file_entry const& fe = m_files[index];
|
internal_file_entry const& fe = m_files[index];
|
||||||
TORRENT_ASSERT(fe.path_index >= -2 && fe.path_index < int(m_paths.size()));
|
return file_path(fe, save_path);
|
||||||
// -2 means this is an absolute path filename
|
|
||||||
if (fe.path_index == -2) return fe.filename();
|
|
||||||
|
|
||||||
// -1 means no path
|
|
||||||
if (fe.path_index == -1) return combine_path(save_path, fe.filename());
|
|
||||||
|
|
||||||
return combine_path(save_path, combine_path(m_paths[fe.path_index], fe.filename()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_storage::file_name(int index) const
|
std::string file_storage::file_name(int index) const
|
||||||
|
@ -581,7 +598,8 @@ namespace libtorrent
|
||||||
return m_file_base[index];
|
return m_file_base[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_storage::file_path(internal_file_entry const& fe, std::string const& save_path) const
|
std::string file_storage::file_path(internal_file_entry const& fe
|
||||||
|
, std::string const& save_path) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(fe.path_index >= -2 && fe.path_index < int(m_paths.size()));
|
TORRENT_ASSERT(fe.path_index >= -2 && fe.path_index < int(m_paths.size()));
|
||||||
// -2 means this is an absolute path filename
|
// -2 means this is an absolute path filename
|
||||||
|
@ -590,7 +608,15 @@ namespace libtorrent
|
||||||
// -1 means no path
|
// -1 means no path
|
||||||
if (fe.path_index == -1) return combine_path(save_path, fe.filename());
|
if (fe.path_index == -1) return combine_path(save_path, fe.filename());
|
||||||
|
|
||||||
return combine_path(save_path, combine_path(m_paths[fe.path_index], fe.filename()));
|
if (fe.no_root_dir)
|
||||||
|
return combine_path(save_path
|
||||||
|
, combine_path(m_paths[fe.path_index]
|
||||||
|
, fe.filename()));
|
||||||
|
|
||||||
|
return combine_path(save_path
|
||||||
|
, combine_path(m_name
|
||||||
|
, combine_path(m_paths[fe.path_index]
|
||||||
|
, fe.filename())));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_storage::file_name(internal_file_entry const& fe) const
|
std::string file_storage::file_name(internal_file_entry const& fe) const
|
||||||
|
|
|
@ -78,11 +78,13 @@ void setup_test_storage(file_storage& st)
|
||||||
int test_main()
|
int test_main()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
// test rename_file
|
||||||
file_storage st;
|
file_storage st;
|
||||||
setup_test_storage(st);
|
setup_test_storage(st);
|
||||||
|
|
||||||
st.rename_file(0, combine_path("test", combine_path("c", "d")));
|
st.rename_file(0, combine_path("test", combine_path("c", "d")));
|
||||||
TEST_EQUAL(st.file_path(0, "."), combine_path(".", combine_path("test", combine_path("c", "d"))));
|
TEST_EQUAL(st.file_path(0, "."), combine_path(".", combine_path("test"
|
||||||
|
, combine_path("c", "d"))));
|
||||||
|
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
st.rename_file(0, "c:\\tmp\\a");
|
st.rename_file(0, "c:\\tmp\\a");
|
||||||
|
@ -93,6 +95,16 @@ int test_main()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// test set_name
|
||||||
|
file_storage st;
|
||||||
|
setup_test_storage(st);
|
||||||
|
|
||||||
|
st.set_name("test_2");
|
||||||
|
TEST_EQUAL(st.file_path(0, "."), combine_path(".", combine_path("test_2"
|
||||||
|
, "a")));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
file_storage st;
|
file_storage st;
|
||||||
st.add_file("a", 10000);
|
st.add_file("a", 10000);
|
||||||
|
|
Loading…
Reference in New Issue