diff --git a/libtorrent/src/file.cpp b/libtorrent/src/file.cpp index 71bc795a4..29b1fc5c7 100755 --- a/libtorrent/src/file.cpp +++ b/libtorrent/src/file.cpp @@ -248,15 +248,15 @@ namespace libtorrent void set_size(size_type s) { size_type pos = tell(); - seek(1, 0); + seek(s); char dummy = 0; read(&dummy, 1); - seek(1, 0); + seek(s); write(&dummy, 1); - seek(pos, 1); + seek(pos); } - size_type seek(size_type offset, int m) + size_type seek(size_type offset, int m = 1) { assert(m_open_mode); assert(m_fd != -1); @@ -345,3 +345,4 @@ namespace libtorrent } } + diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 0623dfeb6..abe5cae8e 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -309,7 +309,7 @@ namespace libtorrent #endif } catch (std::exception&) {} - if (size != s->first + if ((compact_mode && size != s->first) || (!compact_mode && size < s->first)) { if (error) *error = "filesize mismatch for file '" @@ -319,7 +319,7 @@ namespace libtorrent + " bytes"; return false; } - if (time != s->second + if ((compact_mode && time != s->second) || (!compact_mode && time < s->second)) { if (error) *error = "timestamp mismatch for file '" @@ -884,13 +884,13 @@ namespace libtorrent if (left_to_write > 0) { - #ifndef NDEBUG +#ifndef NDEBUG if (write_bytes > 0) ++counter; - #endif +#endif ++file_iter; assert(file_iter != m_info.end_files()); - path p = m_save_path / file_iter->path; + path p = m_save_path / file_iter->path; file_offset = 0; out = m_files.open_file( this, p, file::out | file::in); @@ -1613,22 +1613,42 @@ namespace libtorrent m_unallocated_slots.push_back(i); } - if (!m_compact_mode && !m_unallocated_slots.empty()) - { - m_state = state_allocating; - return false; - } - else + if (m_compact_mode || m_unallocated_slots.empty()) { m_state = state_finished; return true; } } - m_state = state_create_files; + m_current_slot = 0; + m_state = state_full_check; return false; } +/* + state chart: + + check_fastresume() + + | | + | v + | +------------+ + | | full_check | + | +------------+ + | | + | v + | +------------+ +--------------+ + | | allocating |-->| create_files | + | +------------+ +--------------+ + | | | + | v | + | +----------+ | + +---->| finished |<--------+ + +----------+ + +*/ + + // performs the full check and full allocation // (if necessary). returns true if finished and // false if it should be called again @@ -1654,6 +1674,15 @@ namespace libtorrent return std::make_pair(true, 1.f); } + if (int(m_unallocated_slots.size()) == m_info.num_pieces() + && !m_fill_mode) + { + // if there is not a single file on disk, just + // create the files + m_state = state_create_files; + return std::make_pair(false, 1.f); + } + // if we're not in compact mode, make sure the // pieces are spread out and placed at their // final position. @@ -1682,10 +1711,19 @@ namespace libtorrent { m_storage->initialize(!m_fill_mode && !m_compact_mode); - m_current_slot = 0; - m_state = state_full_check; - m_piece_data.resize(int(m_info.piece_length())); - return std::make_pair(false, 0.f); + if (!m_unallocated_slots.empty()) + { + assert(!m_fill_mode); + assert(!m_compact_mode); + std::vector().swap(m_unallocated_slots); + std::fill(m_slot_to_piece.begin(), m_slot_to_piece.end(), int(unassigned)); + m_free_slots.resize(m_info.num_pieces()); + for (int i = 0; i < m_info.num_pieces(); ++i) + m_free_slots[i] = i; + } + + m_state = state_finished; + return std::make_pair(true, 1.f); } assert(m_state == state_full_check); @@ -1697,6 +1735,7 @@ namespace libtorrent try { + m_piece_data.resize(int(m_info.piece_length())); int piece_size = int(m_info.piece_size(m_current_slot)); int num_read = m_storage->read(&m_piece_data[0] , m_current_slot, 0, piece_size); @@ -2323,3 +2362,4 @@ namespace libtorrent #endif } // namespace libtorrent +