2022-01-20 18:27:56 +00:00
|
|
|
// This file Copyright © 2007-2022 Mnemosyne LLC.
|
2022-02-07 16:25:02 +00:00
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
2022-01-20 18:27:56 +00:00
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2021-11-24 14:48:52 +00:00
|
|
|
|
|
|
|
#include "transmission.h"
|
|
|
|
|
|
|
|
#include "block-info.h"
|
2021-12-15 21:25:42 +00:00
|
|
|
#include "tr-assert.h"
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-15 05:38:59 +00:00
|
|
|
void tr_block_info::initSizes(uint64_t total_size_in, uint32_t piece_size_in) noexcept
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
2022-04-14 01:22:59 +00:00
|
|
|
TR_ASSERT(piece_size_in == 0 || piece_size_in >= BlockSize);
|
|
|
|
if (piece_size_in == 0)
|
2021-11-24 14:48:52 +00:00
|
|
|
{
|
2021-11-25 20:30:13 +00:00
|
|
|
*this = {};
|
2021-11-24 14:48:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
total_size_ = total_size_in;
|
|
|
|
piece_size_ = piece_size_in;
|
|
|
|
n_pieces_ = (total_size_ + piece_size_ - 1) / piece_size_;
|
|
|
|
n_blocks_ = (total_size_ + BlockSize - 1) / BlockSize;
|
|
|
|
|
2022-04-15 05:38:59 +00:00
|
|
|
uint32_t remainder = total_size_ % piece_size_;
|
2022-04-14 01:22:59 +00:00
|
|
|
final_piece_size_ = remainder != 0U ? remainder : piece_size_;
|
|
|
|
|
|
|
|
remainder = total_size_ % BlockSize;
|
|
|
|
final_block_size_ = remainder != 0U ? remainder : BlockSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr_block_info::Location tr_block_info::byteLoc(uint64_t byte_idx) const noexcept
|
|
|
|
{
|
|
|
|
TR_ASSERT(byte_idx <= totalSize());
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
if (!isInitialized())
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
auto loc = Location{};
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
loc.byte = byte_idx;
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
if (byte_idx == totalSize()) // handle 0-byte files at the end of a torrent
|
|
|
|
{
|
|
|
|
loc.block = blockCount() - 1;
|
|
|
|
loc.piece = pieceCount() - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
loc.block = byte_idx / BlockSize;
|
|
|
|
loc.piece = byte_idx / pieceSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
loc.block_offset = static_cast<uint32_t>(loc.byte - (uint64_t{ loc.block } * BlockSize));
|
|
|
|
loc.piece_offset = static_cast<uint32_t>(loc.byte - (uint64_t{ loc.piece } * pieceSize()));
|
|
|
|
|
|
|
|
return loc;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr_block_info::Location tr_block_info::blockLoc(tr_block_index_t block) const noexcept
|
|
|
|
{
|
|
|
|
TR_ASSERT(block < blockCount());
|
|
|
|
|
|
|
|
return byteLoc(uint64_t{ block } * BlockSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
tr_block_info::Location tr_block_info::pieceLoc(tr_piece_index_t piece, uint32_t offset, uint32_t length) const noexcept
|
|
|
|
{
|
|
|
|
TR_ASSERT(piece < pieceCount());
|
2021-11-24 14:48:52 +00:00
|
|
|
|
2022-04-14 01:22:59 +00:00
|
|
|
return byteLoc(uint64_t{ piece } * pieceSize() + offset + length);
|
2021-11-24 14:48:52 +00:00
|
|
|
}
|