sparse files fixes. now sets the size of the files in case sparse files are supported

This commit is contained in:
Arvid Norberg 2007-04-19 03:06:15 +00:00
parent a35c1ef1a5
commit 92cf13c2c2
5 changed files with 79 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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

View File

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