AUTO_LT_SYNC
authorJosh Davis <[email protected]>
Sun, 5 Oct 2008 02:08:23 +0000 (5 13:08 +1100)
committerJosh Davis <[email protected]>
Sun, 5 Oct 2008 02:08:23 +0000 (5 13:08 +1100)
libtorrent/bindings/python/src/ip_filter.cpp
libtorrent/include/libtorrent/file_storage.hpp
libtorrent/src/bt_peer_connection.cpp
libtorrent/src/file_storage.cpp
libtorrent/src/storage.cpp
libtorrent/src/torrent.cpp
libtorrent/src/torrent_info.cpp

index eed2161..7ce72cf 100644 (file)
@@ -13,16 +13,21 @@ namespace
 {
     void add_rule(ip_filter& filter, std::string start, std::string end, int flags)
     {
-        return filter.add_rule(address_v4::from_string(start), address_v4::from_string(end), flags);
+        return filter.add_rule(address::from_string(start), address::from_string(end), flags);
+    }
+    
+    int _access(ip_filter& filter, std::string addr)
+    {
+        return filter.access(address::from_string(addr));
     }
 }
 
 void bind_ip_filter()
 {
     class_<ip_filter>("ip_filter")
-        .def("add_rule", &add_rule)
-        .def("access", allow_threads(&ip_filter::access))
-        .def_readonly("export_filter", allow_threads(&ip_filter::export_filter))
+        .def("add_rule", add_rule)
+        .def("access", _access)
+        .def("export_filter", allow_threads(&ip_filter::export_filter))
     ;
 }
 
index 47fcb92..f70583d 100644 (file)
@@ -56,7 +56,7 @@ namespace libtorrent
 
        struct TORRENT_EXPORT file_entry
        {
-               file_entry(): offset(0), size(0), file_base(0) {}
+               file_entry(): offset(0), size(0), file_base(0), pad_file(false) {}
 
                fs::path path;
                size_type offset; // the offset of this file inside the torrent
@@ -65,6 +65,7 @@ namespace libtorrent
                // This is always 0 unless parts of the torrent is
                // compressed into a single file, such as a so-called part file.
                size_type file_base;
+               bool pad_file:1;
        };
 
        struct TORRENT_EXPORT file_slice
@@ -84,7 +85,7 @@ namespace libtorrent
                bool is_valid() const { return m_piece_length > 0; }
 
                void add_file(file_entry const& e);
-               void add_file(fs::path const& p, size_type size);
+               void add_file(fs::path const& p, size_type size, bool pad_file = false);
                void rename_file(int index, std::string const& new_filename);
 
                std::vector<file_slice> map_block(int piece, size_type offset
index 28c3efa..7d59cbd 100644 (file)
@@ -814,12 +814,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 1)
                {
                        disconnect("'choke' message size != 1", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                incoming_choke();
@@ -849,12 +849,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 1)
                {
                        disconnect("'unchoke' message size != 1", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                incoming_unchoke();
@@ -869,12 +869,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 1)
                {
                        disconnect("'interested' message size != 1", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                incoming_interested();
@@ -889,12 +889,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 1)
                {
                        disconnect("'not interested' message size != 1", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                incoming_not_interested();
@@ -909,12 +909,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 5)
                {
                        disconnect("'have' message size != 5", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                buffer::const_interval recv_buffer = receive_buffer();
@@ -938,6 +938,7 @@ namespace libtorrent
                boost::shared_ptr<torrent> t = associated_torrent().lock();
                TORRENT_ASSERT(t);
 
+               m_statistics.received_bytes(0, received);
                // if we don't have the metedata, we cannot
                // verify the bitfield size
                if (t->valid_metadata()
@@ -951,7 +952,6 @@ namespace libtorrent
                        return;
                }
 
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                buffer::const_interval recv_buffer = receive_buffer();
@@ -972,12 +972,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 13)
                {
                        disconnect("'request' message size != 13", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                buffer::const_interval recv_buffer = receive_buffer();
@@ -1008,7 +1008,10 @@ namespace libtorrent
                {
                        TORRENT_ASSERT(!has_disk_receive_buffer());
                        if (!allocate_disk_receive_buffer(packet_size() - 9))
+                       {
+                               m_statistics.received_bytes(0, received);
                                return;
+                       }
                }
                TORRENT_ASSERT(has_disk_receive_buffer());
 
@@ -1054,12 +1057,12 @@ namespace libtorrent
                INVARIANT_CHECK;
 
                TORRENT_ASSERT(received > 0);
+               m_statistics.received_bytes(0, received);
                if (packet_size() != 13)
                {
                        disconnect("'cancel' message size != 13", 2);
                        return;
                }
-               m_statistics.received_bytes(0, received);
                if (!packet_finished()) return;
 
                buffer::const_interval recv_buffer = receive_buffer();
index dd732be..fd38c42 100644 (file)
@@ -128,7 +128,7 @@ namespace libtorrent
                return ret;
        }
 
-       void file_storage::add_file(fs::path const& file, size_type size)
+       void file_storage::add_file(fs::path const& file, size_type size, bool pad_file)
        {
                TORRENT_ASSERT(size >= 0);
 #if BOOST_VERSION < 103600
@@ -151,6 +151,7 @@ namespace libtorrent
                }
                TORRENT_ASSERT(m_name == *file.begin());
                file_entry e;
+               e.pad_file = pad_file;
                m_files.push_back(e);
                m_files.back().size = size;
                m_files.back().path = file;
@@ -160,7 +161,7 @@ namespace libtorrent
 
        void file_storage::add_file(file_entry const& e)
        {
-               add_file(e.path, e.size);
+               add_file(e.path, e.size, e.pad_file);
        }
 }
 
index 82ed21f..32c8e9b 100644 (file)
@@ -519,9 +519,12 @@ namespace libtorrent
 #endif
                        }
 
+                       int file_index = file_iter - files().begin();
+
                        // if the file is empty, just create it. But also make sure
                        // the directory exists.
-                       if (file_iter->size == 0)
+                       if (file_iter->size == 0 && (int(m_file_priority.size()) <= file_index
+                               || m_file_priority[file_index] > 0))
                        {
                                file(m_save_path / file_iter->path, file::out, ec);
                                if (ec)
@@ -535,9 +538,10 @@ namespace libtorrent
 #ifndef BOOST_NO_EXCEPTIONS
                        try {
 #endif
-                       // don't allocate files with priority 0
-                       int file_index = file_iter - files().begin();
-                       if (allocate_files && (int(m_file_priority.size()) <= file_index
+                       // don't allocate files with priority 0 or files
+                       // that are pad files
+                       if (allocate_files && !file_iter->pad_file
+                               && (int(m_file_priority.size()) <= file_index
                                || m_file_priority[file_index] > 0))
                        {
                                error_code ec;
@@ -1023,38 +1027,13 @@ namespace libtorrent
 
                        file_offset -= file_iter->size;
                        ++file_iter;
+                       TORRENT_ASSERT(file_iter != files().end());
                }
-
                int buf_pos = 0;
                error_code ec;
-               boost::shared_ptr<file> in(m_pool.open_file(
-                       this, m_save_path / file_iter->path, file::in, ec));
-               if (!in || ec)
-               {
-                       set_error(m_save_path / file_iter->path, ec);
-                       return -1;
-               }
-               TORRENT_ASSERT(file_offset < file_iter->size);
-               TORRENT_ASSERT(slices[0].offset == file_offset + file_iter->file_base);
-
-               size_type new_pos = in->seek(file_offset + file_iter->file_base, file::begin, ec);
-               if (new_pos != file_offset + file_iter->file_base || ec)
-               {
-                       // the file was not big enough
-                       if (!fill_zero)
-                       {
-                               set_error(m_save_path / file_iter->path, ec);
-                               return -1;
-                       }
-                       std::memset(buf + buf_pos, 0, size - buf_pos);
-                       return size;
-               }
-
-#ifndef NDEBUG
-               size_type in_tell = in->tell(ec);
-               TORRENT_ASSERT(in_tell == file_offset + file_iter->file_base && !ec);
-#endif
 
+               boost::shared_ptr<file> in;
                int left_to_read = size;
                int slot_size = static_cast<int>(m_files.piece_size(slot));
 
@@ -1069,73 +1048,71 @@ namespace libtorrent
                int counter = 0;
 #endif
 
-               while (left_to_read > 0)
+               int read_bytes;
+               for (;left_to_read > 0; ++file_iter, left_to_read -= read_bytes
+                       , buf_pos += read_bytes)
                {
-                       int read_bytes = left_to_read;
+                       TORRENT_ASSERT(file_iter != files().end());
+                       TORRENT_ASSERT(buf_pos >= 0);
+
+                       read_bytes = left_to_read;
                        if (file_offset + read_bytes > file_iter->size)
-                               read_bytes = static_cast<int>(file_iter->size - file_offset);
+                               read_bytes = std::max(static_cast<int>(file_iter->size - file_offset), 0);
+
+                       if (read_bytes == 0) continue;
 
-                       if (read_bytes > 0)
-                       {
 #ifndef NDEBUG
-                               TORRENT_ASSERT(int(slices.size()) > counter);
-                               size_type slice_size = slices[counter].size;
-                               TORRENT_ASSERT(slice_size == read_bytes);
-                               TORRENT_ASSERT(files().at(slices[counter].file_index).path
-                                       == file_iter->path);
+                       TORRENT_ASSERT(int(slices.size()) > counter);
+                       size_type slice_size = slices[counter].size;
+                       TORRENT_ASSERT(slice_size == read_bytes);
+                       TORRENT_ASSERT(files().at(slices[counter].file_index).path
+                               == file_iter->path);
+                       ++counter;
 #endif
 
-                               int actual_read = int(in->read(buf + buf_pos, read_bytes, ec));
+                       if (file_iter->pad_file)
+                       {
+                               std::memset(buf + buf_pos, 0, read_bytes);
+                               continue;
+                       }
 
-                               if (read_bytes != actual_read || ec)
-                               {
-                                       // the file was not big enough
-                                       if (actual_read > 0) buf_pos += actual_read;
-                                       if (!fill_zero)
-                                       {
-                                               set_error(m_save_path / file_iter->path, ec);
-                                               return -1;
-                                       }
-                                       std::memset(buf + buf_pos, 0, size - buf_pos);
-                                       return size;
-                               }
+                       fs::path path = m_save_path / file_iter->path;
 
-                               left_to_read -= read_bytes;
-                               buf_pos += read_bytes;
-                               TORRENT_ASSERT(buf_pos >= 0);
-                               file_offset += read_bytes;
+                       error_code ec;
+                       in = m_pool.open_file(this, path, file::in, ec);
+                       if (!in || ec)
+                       {
+                               set_error(path, ec);
+                               return -1;
                        }
-
-                       if (left_to_read > 0)
+                       size_type pos = in->seek(file_iter->file_base + file_offset, file::begin, ec);
+                       if (pos != file_iter->file_base + file_offset || ec)
                        {
-                               ++file_iter;
-#ifndef NDEBUG
-                               // empty files are not returned by map_block, so if
-                               // this file was empty, don't increment the slice counter
-                               if (read_bytes > 0) ++counter;
-#endif
-                               fs::path path = m_save_path / file_iter->path;
-
-                               file_offset = 0;
-                               error_code ec;
-                               in = m_pool.open_file( this, path, file::in, ec);
-                               if (!in || ec)
+                               if (!fill_zero)
                                {
-                                       set_error(path, ec);
+                                       set_error(m_save_path / file_iter->path, ec);
                                        return -1;
                                }
-                               size_type pos = in->seek(file_iter->file_base, file::begin, ec);
-                               if (pos != file_iter->file_base || ec)
+                               std::memset(buf + buf_pos, 0, size - buf_pos);
+                               return size;
+                       }
+                       file_offset = 0;
+
+                       int actual_read = int(in->read(buf + buf_pos, read_bytes, ec));
+
+                       if (read_bytes != actual_read || ec)
+                       {
+                               // the file was not big enough
+                               if (actual_read > 0) buf_pos += actual_read;
+                               if (!fill_zero)
                                {
-                                       if (!fill_zero)
-                                       {
-                                               set_error(m_save_path / file_iter->path, ec);
-                                               return -1;
-                                       }
-                                       std::memset(buf + buf_pos, 0, size - buf_pos);
-                                       return size;
+                                       set_error(m_save_path / file_iter->path, ec);
+                                       return -1;
                                }
+                               std::memset(buf + buf_pos, 0, size - buf_pos);
+                               return size;
                        }
+
                }
                return result;
        }
@@ -1159,6 +1136,7 @@ namespace libtorrent
 #endif
 
                size_type start = slot * (size_type)m_files.piece_length() + offset;
+               TORRENT_ASSERT(start + size <= m_files.total_size());
 
                // find the file iterator and file offset
                size_type file_offset = start;
@@ -1174,27 +1152,10 @@ namespace libtorrent
                        TORRENT_ASSERT(file_iter != files().end());
                }
 
-               fs::path p(m_save_path / file_iter->path);
+               int buf_pos = 0;
                error_code ec;
-               boost::shared_ptr<file> out = m_pool.open_file(
-                       this, p, file::out | file::in, ec);
-
-               if (!out || ec)
-               {
-                       set_error(p, ec);
-                       return -1;
-               }
-               TORRENT_ASSERT(file_offset < file_iter->size);
-               TORRENT_ASSERT(slices[0].offset == file_offset + file_iter->file_base);
-
-               size_type pos = out->seek(file_offset + file_iter->file_base, file::begin, ec);
-
-               if (pos != file_offset + file_iter->file_base || ec)
-               {
-                       set_error(p, ec);
-                       return -1;
-               }
 
+               boost::shared_ptr<file> out;
                int left_to_write = size;
                int slot_size = static_cast<int>(m_files.piece_size(slot));
 
@@ -1203,72 +1164,62 @@ namespace libtorrent
 
                TORRENT_ASSERT(left_to_write >= 0);
 
-               int buf_pos = 0;
 #ifndef NDEBUG
                int counter = 0;
 #endif
-               while (left_to_write > 0)
-               {
-                       int write_bytes = left_to_write;
-                       if (file_offset + write_bytes > file_iter->size)
-                       {
-                               TORRENT_ASSERT(file_iter->size >= file_offset);
-                               write_bytes = static_cast<int>(file_iter->size - file_offset);
-                       }
 
-                       if (write_bytes > 0)
-                       {
-                               TORRENT_ASSERT(int(slices.size()) > counter);
-                               TORRENT_ASSERT(slices[counter].size == write_bytes);
-                               TORRENT_ASSERT(files().at(slices[counter].file_index).path
-                                       == file_iter->path);
+               int write_bytes;
+               for (;left_to_write > 0; ++file_iter, left_to_write -= write_bytes
+                       , buf_pos += write_bytes)
+               {
+                       TORRENT_ASSERT(file_iter != files().end());
+                       TORRENT_ASSERT(buf_pos >= 0);
 
-                               TORRENT_ASSERT(buf_pos >= 0);
-                               TORRENT_ASSERT(write_bytes >= 0);
-                               error_code ec;
-                               size_type written = out->write(buf + buf_pos, write_bytes, ec);
+                       write_bytes = left_to_write;
+                       if (file_offset + write_bytes > file_iter->size)
+                               write_bytes = std::max(static_cast<int>(file_iter->size - file_offset), 0);
 
-                               if (written != write_bytes || ec)
-                               {
-                                       set_error(m_save_path / file_iter->path, ec);
-                                       return -1;
-                               }
+                       if (write_bytes == 0) continue;
 
-                               left_to_write -= write_bytes;
-                               buf_pos += write_bytes;
-                               TORRENT_ASSERT(buf_pos >= 0);
-                               file_offset += write_bytes;
-                               TORRENT_ASSERT(file_offset <= file_iter->size);
-                       }
-
-                       if (left_to_write > 0)
-                       {
 #ifndef NDEBUG
-                               if (write_bytes > 0) ++counter;
+                       TORRENT_ASSERT(int(slices.size()) > counter);
+                       size_type slice_size = slices[counter].size;
+                       TORRENT_ASSERT(slice_size == write_bytes);
+                       TORRENT_ASSERT(files().at(slices[counter].file_index).path
+                               == file_iter->path);
+                       ++counter;
 #endif
-                               ++file_iter;
 
-                               TORRENT_ASSERT(file_iter != files().end());
-                               fs::path p = m_save_path / file_iter->path;
-                               file_offset = 0;
-                               error_code ec;
-                               out = m_pool.open_file(
-                                       this, p, file::out | file::in, ec);
+                       if (file_iter->pad_file)
+                               continue;
 
-                               if (!out || ec)
-                               {
-                                       set_error(p, ec);
-                                       return -1;
-                               }
+                       fs::path path = m_save_path / file_iter->path;
 
-                               size_type pos = out->seek(file_iter->file_base, file::begin, ec);
+                       error_code ec;
+                       out = m_pool.open_file(this, path, file::in | file::out, ec);
+                       if (!out || ec)
+                       {
+                               set_error(path, ec);
+                               return -1;
+                       }
+                       size_type pos = out->seek(file_iter->file_base + file_offset, file::begin, ec);
+                       if (pos != file_iter->file_base + file_offset || ec)
+                       {
+                               set_error(m_save_path / file_iter->path, ec);
+                               return -1;
+                       }
+                       file_offset = 0;
 
-                               if (pos != file_iter->file_base || ec)
-                               {
-                                       set_error(p, ec);
-                                       return -1;
-                               }
+                       int actual_written = int(out->write(buf + buf_pos, write_bytes, ec));
+
+                       if (write_bytes != actual_written || ec)
+                       {
+                               // the file was not big enough
+                               if (actual_written > 0) buf_pos += actual_written;
+                               set_error(m_save_path / file_iter->path, ec);
+                               return -1;
                        }
+
                }
                return size;
        }
index 7a590f9..6644a95 100644 (file)
@@ -506,6 +506,27 @@ namespace libtorrent
                        }
                }
        
+               TORRENT_ASSERT(m_block_size > 0);
+               int file = 0;
+               for (file_storage::iterator i = m_torrent_file->files().begin()
+                       , end(m_torrent_file->files().end()); i != end; ++i, ++file)
+               {
+                       if (!i->pad_file) continue;
+                       
+                       peer_request pr = m_torrent_file->map_file(file, 0, m_torrent_file->file_at(file).size);
+                       int off = pr.start % m_block_size;
+                       if (off != 0) { pr.length -= m_block_size - off; pr.start += m_block_size - off; }
+                       TORRENT_ASSERT((pr.start % m_block_size) == 0);
+
+                       int blocks_per_piece = m_torrent_file->piece_length() / m_block_size;
+                       piece_block pb(pr.piece, pr.start / m_block_size);
+                       for (; pr.length >= m_block_size; pr.length -= m_block_size, ++pb.block_index)
+                       {
+                               if (pb.block_index == blocks_per_piece) { pb.block_index = 0; ++pb.piece_index; }
+                               m_picker->mark_as_finished(pb, 0);
+                       }
+               }
+
                m_storage->async_check_fastresume(&m_resume_entry
                        , bind(&torrent::on_resume_data_checked
                        , shared_from_this(), _1, _2));
@@ -3278,6 +3299,9 @@ namespace libtorrent
        {
                INVARIANT_CHECK;
 
+               TORRENT_ASSERT(is_finished());
+               TORRENT_ASSERT(m_state != torrent_status::finished && m_state != torrent_status::seeding);
+
                if (alerts().should_post<torrent_finished_alert>())
                {
                        alerts().post_alert(torrent_finished_alert(
@@ -3408,7 +3432,10 @@ namespace libtorrent
                TORRENT_ASSERT(m_torrent_file->is_valid());
                INVARIANT_CHECK;
 
-               set_state(torrent_status::downloading);
+               // we might be finished already, in which case we should
+               // not switch to downloading mode.
+               if (m_state != torrent_status::finished)
+                       set_state(torrent_status::downloading);
 
                if (m_ses.m_alerts.should_post<torrent_checked_alert>())
                {
@@ -4442,6 +4469,15 @@ namespace libtorrent
        
        void torrent::set_state(torrent_status::state_t s)
        {
+#ifndef NDEBUG
+               if (s == torrent_status::seeding)
+                       TORRENT_ASSERT(is_seed());
+               if (s == torrent_status::finished)
+                       TORRENT_ASSERT(is_finished());
+               if (s == torrent_status::downloading && m_state == torrent_status::finished)
+                       TORRENT_ASSERT(!is_finished());
+#endif
+
                if (m_state == s) return;
                m_state = s;
                if (m_ses.m_alerts.should_post<state_changed_alert>())
index 6fb5fa9..f775330 100644 (file)
@@ -187,6 +187,16 @@ namespace
                verify_encoding(target);
                if (target.path.is_complete())
                        return false;
+
+               // bitcomet pad file
+
+#if BOOST_VERSION < 103600
+               if (target.path.leaf().substr(0, 18) == "_____padding_file_")
+#else
+               if (target.path.filename().substr(0, 18) == "_____padding_file_")
+#endif
+                       target.pad_file = true;
+
                return true;
        }
 
@@ -416,6 +426,13 @@ namespace libtorrent
                        e.path = name;
                        e.offset = 0;
                        e.size = info.dict_find_int_value("length", -1);
+                       // bitcomet pad file
+#if BOOST_VERSION < 103600
+                       if (e.path.leaf().substr(0, 18) == "_____padding_file_")
+#else
+                       if (e.path.filename().substr(0, 18) == "_____padding_file_")
+#endif
+                               e.pad_file = true;
                        if (e.size < 0)
                        {
                                error = "invalid length of torrent";