ddup_bak/chunks/
reader.rs

1use super::ChunkIndex;
2use crate::archive::entries::FileEntry;
3use std::io::Read;
4
5pub struct EntryReader {
6    pub entry: Box<FileEntry>,
7    pub chunk_index: ChunkIndex,
8
9    finished: bool,
10    buffer: Vec<u8>,
11    buffer_pos: usize,
12}
13
14impl EntryReader {
15    pub fn new(entry: Box<FileEntry>, chunk_index: ChunkIndex) -> Self {
16        Self {
17            entry,
18            chunk_index,
19            finished: false,
20            buffer: Vec::new(),
21            buffer_pos: 0,
22        }
23    }
24
25    fn fill_buffer(&mut self) -> std::io::Result<()> {
26        if self.finished {
27            return Ok(());
28        }
29
30        if self.buffer_pos < self.buffer.len() {
31            return Ok(());
32        }
33
34        self.buffer.clear();
35        self.buffer_pos = 0;
36
37        let chunk_id = crate::varint::decode_u64(&mut self.entry);
38        if chunk_id == 0 {
39            self.finished = true;
40            return Ok(());
41        }
42
43        let mut chunk = self.chunk_index.read_chunk_id_content(chunk_id)?;
44        chunk.read_to_end(&mut self.buffer)?;
45
46        Ok(())
47    }
48}
49
50impl Read for EntryReader {
51    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
52        if self.buffer_pos >= self.buffer.len() {
53            self.fill_buffer()?;
54        }
55
56        if self.buffer_pos >= self.buffer.len() {
57            return Ok(0);
58        }
59
60        let bytes_available = self.buffer.len() - self.buffer_pos;
61        let bytes_to_copy = std::cmp::min(bytes_available, buf.len());
62
63        buf[..bytes_to_copy]
64            .copy_from_slice(&self.buffer[self.buffer_pos..self.buffer_pos + bytes_to_copy]);
65
66        self.buffer_pos += bytes_to_copy;
67
68        if bytes_to_copy < buf.len() && self.buffer_pos >= self.buffer.len() && !self.finished {
69            let additional_bytes = self.read(&mut buf[bytes_to_copy..])?;
70            return Ok(bytes_to_copy + additional_bytes);
71        }
72
73        Ok(bytes_to_copy)
74    }
75}