Skip to main content

aria2_core/segment/
pieced_segment.rs

1use crate::error::{Aria2Error, Result};
2use aria2_protocol::bittorrent::piece::bitfield::Bitfield;
3
4pub struct PiecedSegment {
5    piece_index: usize,
6    piece_length: u64,
7    bitfield: Bitfield,
8}
9
10impl PiecedSegment {
11    pub fn new(piece_index: usize, piece_length: u64, num_blocks: usize) -> Self {
12        PiecedSegment {
13            piece_index,
14            piece_length,
15            bitfield: Bitfield::new(num_blocks),
16        }
17    }
18
19    pub fn piece_index(&self) -> usize {
20        self.piece_index
21    }
22
23    pub fn piece_length(&self) -> u64 {
24        self.piece_length
25    }
26
27    pub fn num_blocks(&self) -> usize {
28        self.bitfield.len()
29    }
30
31    pub fn is_completed(&self) -> bool {
32        self.bitfield.is_all_set()
33    }
34
35    pub fn mark_block_completed(&mut self, block_index: usize) -> Result<()> {
36        self.bitfield.set(block_index).ok_or_else(|| {
37            Aria2Error::DownloadFailed(format!(
38                "Block index out of range: {} >= {}",
39                block_index,
40                self.bitfield.len()
41            ))
42        })
43    }
44
45    pub fn mark_block_incomplete(&mut self, block_index: usize) -> Result<()> {
46        self.bitfield.clear(block_index).ok_or_else(|| {
47            Aria2Error::DownloadFailed(format!(
48                "Block index out of range: {} >= {}",
49                block_index,
50                self.bitfield.len()
51            ))
52        })
53    }
54
55    pub fn is_block_completed(&self, block_index: usize) -> bool {
56        self.bitfield.test(block_index)
57    }
58
59    pub fn get_next_missing_block(&self) -> Option<usize> {
60        self.bitfield.find_first_clear()
61    }
62
63    pub fn get_completed_blocks(&self) -> Vec<usize> {
64        self.bitfield.iter_set().collect()
65    }
66
67    pub fn get_missing_blocks(&self) -> Vec<usize> {
68        self.bitfield.iter_clear().collect()
69    }
70
71    pub fn completed_blocks_count(&self) -> usize {
72        self.bitfield.count_set()
73    }
74
75    pub fn missing_blocks_count(&self) -> usize {
76        self.bitfield.count_clear()
77    }
78
79    pub fn progress(&self) -> f64 {
80        let total = self.bitfield.len();
81        if total == 0 {
82            0.0
83        } else {
84            (self.completed_blocks_count() as f64 / total as f64) * 100.0
85        }
86    }
87}