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 close();
|
||||
void set_size(size_type size);
|
||||
|
||||
size_type write(const char*, size_type num_bytes);
|
||||
size_type read(char*, size_type num_bytes);
|
||||
|
|
|
@ -89,6 +89,10 @@ namespace libtorrent
|
|||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert(m_open_mode);
|
||||
|
@ -318,6 +329,11 @@ namespace libtorrent
|
|||
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)
|
||||
{
|
||||
return m_impl->seek(pos, m.m_val);
|
||||
|
|
|
@ -238,6 +238,16 @@ namespace libtorrent
|
|||
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)
|
||||
{
|
||||
assert(pos >= 0 || from_where != seek_begin);
|
||||
|
@ -339,6 +349,11 @@ namespace libtorrent
|
|||
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)
|
||||
{
|
||||
return m_impl->seek(pos,impl::seek_mode(m.m_val));
|
||||
|
|
|
@ -372,6 +372,7 @@ namespace libtorrent
|
|||
|
||||
void release_files();
|
||||
|
||||
void initialize();
|
||||
bool move_storage(path save_path);
|
||||
size_type read(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;
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
m_files.release(this);
|
||||
|
@ -830,6 +870,8 @@ namespace libtorrent
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
|
@ -1522,33 +1564,8 @@ namespace libtorrent
|
|||
|
||||
if (m_state == state_create_files)
|
||||
{
|
||||
// first, create all missing directories
|
||||
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();
|
||||
m_storage->initialize();
|
||||
|
||||
// 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_state = state_full_check;
|
||||
m_piece_data.resize(int(m_info.piece_length()));
|
||||
|
|
Loading…
Reference in New Issue