forked from premiere/premiere-libtorrent
sparse files fixes. now sets the size of the files in case sparse files are supported
This commit is contained in:
parent
a35c1ef1a5
commit
92cf13c2c2
|
@ -110,6 +110,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void open(boost::filesystem::path const& p, open_mode m);
|
void open(boost::filesystem::path const& p, open_mode m);
|
||||||
void close();
|
void close();
|
||||||
|
void set_size(size_type size);
|
||||||
|
|
||||||
size_type write(const char*, size_type num_bytes);
|
size_type write(const char*, size_type num_bytes);
|
||||||
size_type read(char*, size_type num_bytes);
|
size_type read(char*, size_type num_bytes);
|
||||||
|
|
|
@ -89,6 +89,10 @@ namespace libtorrent
|
||||||
|
|
||||||
struct TORRENT_EXPORT storage_interface
|
struct TORRENT_EXPORT storage_interface
|
||||||
{
|
{
|
||||||
|
// create directories and set file sizes
|
||||||
|
// (if sparse files are supported)
|
||||||
|
virtual void initialize() = 0;
|
||||||
|
|
||||||
// may throw file_error if storage for slot does not exist
|
// may throw file_error if storage for slot does not exist
|
||||||
virtual size_type read(char* buf, int slot, int offset, int size) = 0;
|
virtual size_type read(char* buf, int slot, int offset, int size) = 0;
|
||||||
|
|
||||||
|
|
16
src/file.cpp
16
src/file.cpp
|
@ -245,6 +245,17 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_size(size_type s)
|
||||||
|
{
|
||||||
|
size_type pos = tell();
|
||||||
|
seek(1, 0);
|
||||||
|
char dummy = 0;
|
||||||
|
read(&dummy, 1);
|
||||||
|
seek(1, 0);
|
||||||
|
write(&dummy, 1);
|
||||||
|
seek(pos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
size_type seek(size_type offset, int m)
|
size_type seek(size_type offset, int m)
|
||||||
{
|
{
|
||||||
assert(m_open_mode);
|
assert(m_open_mode);
|
||||||
|
@ -318,6 +329,11 @@ namespace libtorrent
|
||||||
return m_impl->read(buf, num_bytes);
|
return m_impl->read(buf, num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void file::set_size(size_type s)
|
||||||
|
{
|
||||||
|
m_impl->set_size(s);
|
||||||
|
}
|
||||||
|
|
||||||
size_type file::seek(size_type pos, file::seek_mode m)
|
size_type file::seek(size_type pos, file::seek_mode m)
|
||||||
{
|
{
|
||||||
return m_impl->seek(pos, m.m_val);
|
return m_impl->seek(pos, m.m_val);
|
||||||
|
|
|
@ -238,6 +238,16 @@ namespace libtorrent
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_size(size_type s)
|
||||||
|
{
|
||||||
|
size_type pos = tell();
|
||||||
|
seek(s, seek_begin);
|
||||||
|
if (FALSE == ::SetEndOfFile(m_file_handle))
|
||||||
|
throw_exception("file::set_size");
|
||||||
|
|
||||||
|
seek(pos, seek_begin);
|
||||||
|
}
|
||||||
|
|
||||||
size_type seek(size_type pos, seek_mode from_where)
|
size_type seek(size_type pos, seek_mode from_where)
|
||||||
{
|
{
|
||||||
assert(pos >= 0 || from_where != seek_begin);
|
assert(pos >= 0 || from_where != seek_begin);
|
||||||
|
@ -339,6 +349,11 @@ namespace libtorrent
|
||||||
return m_impl->read(buffer, num_bytes);
|
return m_impl->read(buffer, num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void file::set_size(size_type s)
|
||||||
|
{
|
||||||
|
m_impl->set_size(s);
|
||||||
|
}
|
||||||
|
|
||||||
size_type file::seek(size_type pos, seek_mode m)
|
size_type file::seek(size_type pos, seek_mode m)
|
||||||
{
|
{
|
||||||
return m_impl->seek(pos,impl::seek_mode(m.m_val));
|
return m_impl->seek(pos,impl::seek_mode(m.m_val));
|
||||||
|
|
|
@ -372,6 +372,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void release_files();
|
void release_files();
|
||||||
|
|
||||||
|
void initialize();
|
||||||
bool move_storage(path save_path);
|
bool move_storage(path save_path);
|
||||||
size_type read(char* buf, int slot, int offset, int size);
|
size_type read(char* buf, int slot, int offset, int size);
|
||||||
void write(const char* buf, int slot, int offset, int size);
|
void write(const char* buf, int slot, int offset, int size);
|
||||||
|
@ -391,6 +392,45 @@ namespace libtorrent
|
||||||
file_pool& m_files;
|
file_pool& m_files;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void storage::initialize()
|
||||||
|
{
|
||||||
|
// first, create all missing directories
|
||||||
|
bool sparse = supports_sparse_files(m_save_path);
|
||||||
|
path last_path;
|
||||||
|
for (torrent_info::file_iterator file_iter = m_info.begin_files(),
|
||||||
|
end_iter = m_info.end_files(); file_iter != end_iter; ++file_iter)
|
||||||
|
{
|
||||||
|
path dir = (m_save_path / file_iter->path).branch_path();
|
||||||
|
|
||||||
|
if (dir != last_path)
|
||||||
|
{
|
||||||
|
last_path = dir;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 13400
|
||||||
|
if (!exists_win(last_path))
|
||||||
|
create_directories_win(last_path);
|
||||||
|
#else
|
||||||
|
if (!exists(last_path))
|
||||||
|
create_directories(last_path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the file is empty, just create it. But also make sure
|
||||||
|
// the directory exits.
|
||||||
|
if (file_iter->size == 0)
|
||||||
|
{
|
||||||
|
file(m_save_path / file_iter->path, file::out);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sparse)
|
||||||
|
{
|
||||||
|
m_files.open_file(this, m_save_path / file_iter->path, file::out)
|
||||||
|
->set_size(file_iter->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void storage::release_files()
|
void storage::release_files()
|
||||||
{
|
{
|
||||||
m_files.release(this);
|
m_files.release(this);
|
||||||
|
@ -830,6 +870,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
@ -1522,33 +1564,8 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_state == state_create_files)
|
if (m_state == state_create_files)
|
||||||
{
|
{
|
||||||
// first, create all missing directories
|
m_storage->initialize();
|
||||||
path last_path;
|
|
||||||
for (torrent_info::file_iterator file_iter = m_info.begin_files(),
|
|
||||||
end_iter = m_info.end_files(); file_iter != end_iter; ++file_iter)
|
|
||||||
{
|
|
||||||
path dir = (m_save_path / file_iter->path).branch_path();
|
|
||||||
|
|
||||||
// if the file is empty, just create it. But also make sure
|
|
||||||
// the directory exits.
|
|
||||||
if (dir == last_path
|
|
||||||
&& file_iter->size == 0)
|
|
||||||
file(m_save_path / file_iter->path, file::out);
|
|
||||||
|
|
||||||
if (dir == last_path) continue;
|
|
||||||
last_path = dir;
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 13400
|
|
||||||
if (!exists_win(last_path))
|
|
||||||
create_directories_win(last_path);
|
|
||||||
#else
|
|
||||||
if (!exists(last_path))
|
|
||||||
create_directories(last_path);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (file_iter->size == 0)
|
|
||||||
file(m_save_path / file_iter->path, file::out);
|
|
||||||
}
|
|
||||||
m_current_slot = 0;
|
m_current_slot = 0;
|
||||||
m_state = state_full_check;
|
m_state = state_full_check;
|
||||||
m_piece_data.resize(int(m_info.piece_length()));
|
m_piece_data.resize(int(m_info.piece_length()));
|
||||||
|
|
Loading…
Reference in New Issue