prettified, Windows build broken
[swift-upb.git] / transfer.cpp
1 /*
2  *  transfer.cpp
3  *  p2tp
4  *
5  *  Created by Victor Grishchenko on 10/6/09.
6  *  Copyright 2009 Delft University of Technology. All rights reserved.
7  *
8  */
9 #ifdef _WIN32
10 #include "compat/unixio.h"
11 #else
12 #include <sys/mman.h>
13 #endif
14 #include <errno.h>
15 #include <string>
16 #include <sstream>
17 #include "p2tp.h"
18 #include "compat/util.h"
19
20 using namespace p2tp;
21
22 std::vector<FileTransfer*> FileTransfer::files(20);
23
24 int FileTransfer::instance = 0;
25 #define BINHASHSIZE (sizeof(bin64_t)+sizeof(Sha1Hash))
26
27 #include "ext/seq_picker.cpp"
28
29 // FIXME: separate Bootstrap() and Download(), then Size(), Progress(), SeqProgress()
30
31 FileTransfer::FileTransfer (const char* filename, const Sha1Hash& _root_hash) :
32     file_(filename,_root_hash), hs_in_offset_(0)
33 {
34     if (files.size()<fd()+1)
35         files.resize(fd()+1);
36     files[fd()] = this;
37     picker_ = new SeqPiecePicker(this);
38     if (file_.size())
39         picker_->Randomize(rand()&31&(file_.peak(0).width()-1));
40 }
41
42
43
44 FileTransfer::~FileTransfer ()
45 {
46
47     files[fd()] = NULL;
48 }
49
50
51 FileTransfer* FileTransfer::Find (const Sha1Hash& root_hash) {
52     for(int i=0; i<files.size(); i++)
53         if (files[i] && files[i]->root_hash()==root_hash)
54             return files[i];
55     return NULL;
56 }
57
58
59 void            FileTransfer::OnPexIn (const Address& addr) {
60     for(int i=0; i<hs_in_.size(); i++) {
61         Channel* c = Channel::channels[hs_in_[i]];
62         if (c && c->transfer().fd()==this->fd() && c->peer_==addr)
63             return; // already connected
64     }
65     if (hs_in_.size()<20) {
66         new Channel(this,Channel::sockets[0],addr);
67     } else {
68         pex_in_.push_back(addr);
69         if (pex_in_.size()>1000)
70             pex_in_.pop_front();
71     }
72 }
73
74
75 int        FileTransfer::RevealChannel (int& pex_out_) {
76     pex_out_ -= hs_in_offset_;
77     if (pex_out_<0)
78         pex_out_ = 0;
79     while (pex_out_<hs_in_.size()) {
80         Channel* c = Channel::channels[hs_in_[pex_out_]];
81         if (c && c->transfer().fd()==this->fd()) {
82             pex_out_ += hs_in_offset_ + 1;
83             return c->id;
84         } else {
85             hs_in_[pex_out_] = hs_in_[0];
86             hs_in_.pop_front();
87             hs_in_offset_++;
88         }
89     }
90     pex_out_ += hs_in_offset_;
91     return -1;
92 }
93