ddup_bak/chunks/
reader.rs1use 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}