2021-11-24 14:48:52 +00:00
|
|
|
/*
|
|
|
|
* This file Copyright (C) Mnemosyne LLC
|
|
|
|
*
|
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "transmission.h"
|
|
|
|
|
|
|
|
struct tr_block_info
|
|
|
|
{
|
|
|
|
uint64_t total_size = 0;
|
|
|
|
uint64_t piece_size = 0;
|
|
|
|
uint64_t n_pieces = 0;
|
|
|
|
|
|
|
|
tr_block_index_t n_blocks = 0;
|
|
|
|
tr_block_index_t n_blocks_in_piece = 0;
|
|
|
|
tr_block_index_t n_blocks_in_final_piece = 0;
|
|
|
|
uint32_t block_size = 0;
|
|
|
|
uint32_t final_block_size = 0;
|
|
|
|
uint32_t final_piece_size = 0;
|
|
|
|
|
|
|
|
tr_block_info() = default;
|
2021-11-25 18:26:51 +00:00
|
|
|
tr_block_info(uint64_t total_size_in, uint64_t piece_size_in)
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
2021-11-25 18:26:51 +00:00
|
|
|
initSizes(total_size_in, piece_size_in);
|
2021-11-24 14:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void initSizes(uint64_t total_size_in, uint64_t piece_size_in);
|
|
|
|
|
|
|
|
constexpr tr_piece_index_t pieceForBlock(tr_block_index_t block) const
|
|
|
|
{
|
2021-12-06 03:12:21 +00:00
|
|
|
// if not initialized yet, don't divide by zero
|
|
|
|
if (n_blocks_in_piece == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return block / n_blocks_in_piece;
|
2021-11-24 14:48:52 +00:00
|
|
|
}
|
|
|
|
|
2021-11-26 19:33:56 +00:00
|
|
|
constexpr uint32_t pieceSize(tr_piece_index_t piece) const
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
|
|
|
// how many bytes are in this piece?
|
|
|
|
return piece + 1 == n_pieces ? final_piece_size : piece_size;
|
|
|
|
}
|
|
|
|
|
2021-11-26 19:33:56 +00:00
|
|
|
constexpr uint32_t blockSize(tr_block_index_t block) const
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
|
|
|
// how many bytes are in this block?
|
|
|
|
return block + 1 == n_blocks ? final_block_size : block_size;
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:26:51 +00:00
|
|
|
constexpr tr_piece_index_t pieceOf(uint64_t offset) const
|
|
|
|
{
|
2021-12-06 03:12:21 +00:00
|
|
|
// if not initialized yet, don't divide by zero
|
|
|
|
if (piece_size == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:26:51 +00:00
|
|
|
// handle 0-byte files at the end of a torrent
|
2021-12-06 03:12:21 +00:00
|
|
|
if (offset == total_size)
|
|
|
|
{
|
|
|
|
return n_pieces - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset / piece_size;
|
2021-11-25 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2021-11-24 14:48:52 +00:00
|
|
|
constexpr tr_block_index_t blockOf(uint64_t offset) const
|
|
|
|
{
|
2021-12-06 03:12:21 +00:00
|
|
|
// if not initialized yet, don't divide by zero
|
|
|
|
if (block_size == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:26:51 +00:00
|
|
|
// handle 0-byte files at the end of a torrent
|
2021-12-06 03:12:21 +00:00
|
|
|
if (offset == total_size)
|
|
|
|
{
|
|
|
|
return n_blocks - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset / block_size;
|
2021-11-24 14:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
constexpr uint64_t offset(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
|
|
|
{
|
|
|
|
auto ret = piece_size;
|
|
|
|
ret *= piece;
|
|
|
|
ret += offset;
|
|
|
|
ret += length;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr tr_block_index_t blockOf(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
|
|
|
{
|
|
|
|
return blockOf(this->offset(piece, offset, length));
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:26:51 +00:00
|
|
|
constexpr tr_block_span_t blockSpanForPiece(tr_piece_index_t piece) const
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
|
|
|
if (block_size == 0)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:26:51 +00:00
|
|
|
auto const begin = blockOf(offset(piece, 0));
|
2021-11-26 19:33:56 +00:00
|
|
|
auto const end = 1 + blockOf(offset(piece, pieceSize(piece) - 1));
|
2021-11-25 18:26:51 +00:00
|
|
|
return { begin, end };
|
2021-11-24 14:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t bestBlockSize(uint64_t piece_size);
|
|
|
|
};
|