-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTorrentPieces.cpp
116 lines (97 loc) · 2.48 KB
/
TorrentPieces.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "TorrentPieces.h"
#include "Utility.h"
#include <iostream>
namespace Bittorrent
{
using namespace utility;
TorrentPieces::TorrentPieces()
: blockSize{ 16384 }, pieceSize{ 0 }, totalSize{ 0 }, pieceCount{ 0 }
{
}
valueDictionary TorrentPieces::piecesDataToDictionary(valueDictionary& dict)
{
dict.emplace("piece length", pieceSize);
//pieces
std::string piecesString;
for (size_t i = 0; i < pieces.size(); ++i)
{
for (size_t j = 0; j < pieces.at(i).size(); ++j)
{
piecesString += pieces[i][j];
}
}
dict.emplace("pieces", piecesString);
return dict;
}
//generate piece data from torrent object
void TorrentPieces::torrentToPiecesData(const std::vector<fileObj>& fileList,
const valueDictionary& torrent)
{
for (auto file : fileList)
{
totalSize += file.fileSize;
}
valueDictionary info = boost::get<valueDictionary>(torrent.at("info"));
if (!info.count("piece length"))
{
throw std::invalid_argument("Error: no piece length specified in torrent!");
}
pieceSize = static_cast<long>(boost::get<long long>(info.at("piece length")));
//set pieces
if (!info.count("pieces"))
{
throw std::invalid_argument("Error: no pieces specified in torrent!");
}
std::string tempString = boost::get<std::string>(info.at("pieces"));
const size_t n = tempString.size();
const size_t columns = 20;
const size_t rows = n / columns;
assert(rows * columns == n);
pieces.resize(rows, std::vector<byte>(columns));
for (size_t i = 0; i < rows; ++i)
{
for (size_t j = 0; j < columns; ++j)
{
pieces[i][j] = tempString.at(i * columns + j);
}
}
//update pieceCount
pieceCount = pieces.size();
}
int TorrentPieces::getPieceSize(int piece)
{
if (piece == pieceCount - 1)
{
const int remainder = totalSize % pieceSize;
if (remainder != 0)
{
return remainder;
}
}
return pieceSize;
}
int TorrentPieces::getBlockSize(int piece, int block)
{
if (block == getBlockCount(piece) - 1)
{
const int remainder = getPieceSize(piece) % blockSize;
if (remainder != 0)
{
return remainder;
}
}
return blockSize;
}
int TorrentPieces::getBlockCount(int piece)
{
return std::ceil(getPieceSize(piece) / static_cast<double>(blockSize));
}
std::string TorrentPieces::readablePieceSize()
{
return humanReadableBytes(pieceSize);
}
std::string TorrentPieces::readableTotalSize()
{
return humanReadableBytes(totalSize);
}
}