3 * some transfer-scope code
5 * Created by Victor Grishchenko on 10/6/09.
6 * Copyright 2009 Delft University of Technology. All rights reserved.
14 #include "ext/seq_picker.cpp" // FIXME FIXME FIXME FIXME
16 using namespace swift;
18 std::vector<FileTransfer*> FileTransfer::files(20);
20 #define BINHASHSIZE (sizeof(bin64_t)+sizeof(Sha1Hash))
22 // FIXME: separate Bootstrap() and Download(), then Size(), Progress(), SeqProgress()
24 FileTransfer::FileTransfer (const char* filename, const Sha1Hash& _root_hash) :
25 file_(filename,_root_hash), hs_in_offset_(0), cb_installed(0)
27 if (files.size()<fd()+1)
30 picker_ = new SeqPiecePicker(this);
31 picker_->Randomize(rand()&63);
32 init_time_ = Datagram::Time();
36 void Channel::CloseTransfer (FileTransfer* trans) {
37 for(int i=0; i<Channel::channels.size(); i++)
38 if (Channel::channels[i] && Channel::channels[i]->transfer_==trans)
39 delete Channel::channels[i];
43 void swift::AddProgressCallback (int transfer,ProgressCallback cb,uint8_t agg) {
44 FileTransfer* trans = FileTransfer::file(transfer);
47 trans->cb_agg[trans->cb_installed] = agg;
48 trans->callbacks[trans->cb_installed] = cb;
49 trans->cb_installed++;
53 void swift::ExternallyRetrieved (int transfer,bin64_t piece) {
54 FileTransfer* trans = FileTransfer::file(transfer);
57 trans->ack_out().set(piece); // that easy
61 void swift::RemoveProgressCallback (int transfer, ProgressCallback cb) {
62 FileTransfer* trans = FileTransfer::file(transfer);
65 for(int i=0; i<trans->cb_installed; i++)
66 if (trans->callbacks[i]==cb)
67 trans->callbacks[i]=trans->callbacks[--trans->cb_installed];
71 FileTransfer::~FileTransfer ()
73 Channel::CloseTransfer(this);
79 FileTransfer* FileTransfer::Find (const Sha1Hash& root_hash) {
80 for(int i=0; i<files.size(); i++)
81 if (files[i] && files[i]->root_hash()==root_hash)
87 int swift:: Find (Sha1Hash hash) {
88 FileTransfer* t = FileTransfer::Find(hash);
96 void FileTransfer::OnPexIn (const Address& addr) {
97 for(int i=0; i<hs_in_.size(); i++) {
98 Channel* c = Channel::channel(hs_in_[i]);
99 if (c && c->transfer().fd()==this->fd() && c->peer()==addr)
100 return; // already connected
102 if (hs_in_.size()<20) {
103 new Channel(this,Datagram::default_socket(),addr);
105 pex_in_.push_back(addr);
106 if (pex_in_.size()>1000)
112 int FileTransfer::RevealChannel (int& pex_out_) { // FIXME brainfuck
113 pex_out_ -= hs_in_offset_;
116 while (pex_out_<hs_in_.size()) {
117 Channel* c = Channel::channel(hs_in_[pex_out_]);
118 if (c && c->transfer().fd()==this->fd()) {
119 if (c->is_established()) {
120 pex_out_ += hs_in_offset_ + 1;
125 hs_in_[pex_out_] = hs_in_[0];
130 pex_out_ += hs_in_offset_;