fix set_naem() on file_storage actually affecting save paths

This commit is contained in:
Arvid Norberg 2013-11-17 08:02:16 +00:00
parent 8f2683fe5d
commit 25e53cd799
4 changed files with 89 additions and 39 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);