diff --git a/crates/librqbit/src/peer_info_reader/mod.rs b/crates/librqbit/src/peer_info_reader/mod.rs index 2680488..bd31e27 100644 --- a/crates/librqbit/src/peer_info_reader/mod.rs +++ b/crates/librqbit/src/peer_info_reader/mod.rs @@ -5,7 +5,7 @@ use buffers::{ByteBuf, ByteBufOwned}; use librqbit_core::{ constants::CHUNK_SIZE, hash_id::Id20, - lengths::{last_element_size_u64, ChunkInfo}, + lengths::{last_element_size, ChunkInfo}, torrent_metainfo::TorrentMetaV1Info, }; use parking_lot::{Mutex, RwLock}; @@ -87,7 +87,7 @@ impl HandlerLocked { } fn piece_size(&self, index: u32) -> usize { if index as usize == self.total_pieces - 1 { - last_element_size_u64(self.metadata_size as u64, CHUNK_SIZE as u64) as usize + last_element_size(self.metadata_size as u64, CHUNK_SIZE as u64) as usize } else { CHUNK_SIZE as usize } diff --git a/crates/librqbit_core/src/lengths.rs b/crates/librqbit_core/src/lengths.rs index f3b9802..6aed5dc 100644 --- a/crates/librqbit_core/src/lengths.rs +++ b/crates/librqbit_core/src/lengths.rs @@ -2,9 +2,12 @@ use anyhow::Context; use crate::{constants::CHUNK_SIZE, torrent_metainfo::TorrentMetaV1Info}; -pub const fn last_element_size_u64(total_length: u64, piece_length: u64) -> u64 { +pub fn last_element_size(total_length: T, piece_length: T) -> T +where + T: std::ops::Rem + Default + Eq + Copy, +{ let rem = total_length % piece_length; - if rem == 0 { + if rem == T::default() { return piece_length; } rem @@ -84,7 +87,7 @@ impl Lengths { total_length, chunks_per_piece: (piece_length as u64).div_ceil(CHUNK_SIZE as u64) as u32, last_piece_id: total_pieces - 1, - last_piece_length: last_element_size_u64(total_length, piece_length as u64) as u32, + last_piece_length: last_element_size(total_length, piece_length as u64) as u32, }) } @@ -151,7 +154,6 @@ impl Lengths { } pub fn iter_chunk_infos(&self, index: ValidPieceIndex) -> impl Iterator { - // TODO: test let mut remaining = self.piece_length(index); let absolute_offset = index.0 * self.chunks_per_piece; (0u32..).scan(0, move |offset, idx| { @@ -212,7 +214,7 @@ impl Lengths { } pub const fn chunks_per_piece(&self, index: ValidPieceIndex) -> u32 { if index.0 == self.last_piece_id { - return (self.last_piece_length + CHUNK_SIZE - 1) / CHUNK_SIZE; + return self.last_piece_length.div_ceil(CHUNK_SIZE); } self.chunks_per_piece } @@ -227,14 +229,15 @@ impl Lengths { Some(chunk_index * CHUNK_SIZE) } pub fn chunk_size(&self, piece_index: ValidPieceIndex, chunk_index: u32) -> Option { - // TODO: simplify - let chunks_per_piece = self.chunks_per_piece(piece_index); - let pl = self.piece_length(piece_index); - if chunk_index >= chunks_per_piece { - return None; + let piece_length = self.piece_length(piece_index); + let last_chunk_id = piece_length.div_ceil(CHUNK_SIZE) - 1; + if chunk_index < last_chunk_id { + return Some(CHUNK_SIZE); } - let offset = chunk_index * CHUNK_SIZE; - Some(std::cmp::min(CHUNK_SIZE, pl - offset)) + if chunk_index == last_chunk_id { + return Some(last_element_size(piece_length, CHUNK_SIZE)); + } + return None; } }