@@ -322,18 +322,57 @@ impl TorrentActor {
322322 /// Calculates the total number of bytes downloaded by the torrent. Returns
323323 /// None if the info dict is not present.
324324 pub fn total_bytes_downloaded ( & self ) -> Option < usize > {
325- let completed_pieces = self . bitfield . count_ones ( ) ;
326- let piece_size = self . info_dict ( ) . map ( |info| info. piece_length ) ? as usize ;
325+ let info = self . info_dict ( ) ?;
326+ let total_length = info. total_length ( ) ;
327+ let piece_length = info. piece_length as usize ;
327328
328- let mut total_bytes = completed_pieces * piece_size;
329+ let num_pieces = self . bitfield . len ( ) ;
330+ let mut total_bytes = 0usize ;
329331
330- for block in self . block_map . iter ( ) {
331- total_bytes += BLOCK_SIZE * block. count_ones ( ) ;
332+ // Calculate the size of the last piece
333+ let last_piece_len = if total_length % piece_length == 0 {
334+ piece_length
335+ } else {
336+ total_length % piece_length
337+ } ;
338+
339+ // Sum bytes from completed pieces
340+ for piece_idx in 0 ..num_pieces {
341+ if self . bitfield [ piece_idx] {
342+ let piece_size = if piece_idx == num_pieces - 1 {
343+ last_piece_len
344+ } else {
345+ piece_length
346+ } ;
347+ total_bytes = total_bytes. saturating_add ( piece_size) ;
348+ }
349+ }
350+
351+ // Sum bytes from incomplete pieces via block_map
352+ for ( piece_idx, block) in self . block_map . iter ( ) . enumerate ( ) {
353+ if piece_idx < num_pieces && !self . bitfield [ piece_idx] {
354+ let piece_size = if piece_idx == num_pieces - 1 {
355+ last_piece_len
356+ } else {
357+ piece_length
358+ } ;
359+
360+ let mut piece_offset = 0usize ;
361+ for block_idx in 0 ..block. len ( ) {
362+ if block[ block_idx] {
363+ let block_size = ( piece_size - piece_offset) . min ( BLOCK_SIZE ) ;
364+ total_bytes = total_bytes. saturating_add ( block_size) ;
365+ piece_offset = piece_offset. saturating_add ( block_size) ;
366+ } else {
367+ piece_offset =
368+ piece_offset. saturating_add ( BLOCK_SIZE . min ( piece_size - piece_offset) ) ;
369+ }
370+ }
371+ }
332372 }
333373
334374 Some ( total_bytes)
335375 }
336-
337376 pub fn export ( & self ) -> TorrentExport {
338377 TorrentExport {
339378 info_hash : self . info_hash ( ) ,
0 commit comments