ms_pdb_msf/
stream_reader.rs1use super::*;
2
3pub struct StreamReader<'a, F> {
5 stream: u32,
7 stream_size: u32,
9 is_nil: bool,
10 page_size: PageSize,
12 page_map: &'a [Page],
14 file: &'a F,
16 pos: u64,
18}
19
20impl<'a, F: ReadAt> StreamReader<'a, F> {
21 pub(crate) fn new(
22 pdb: &'a Msf<F>,
23 stream: u32,
24 stream_size: u32,
25 page_map: &'a [Page],
26 pos: u64,
27 ) -> Self {
28 Self {
29 stream,
30 stream_size: if stream_size == NIL_STREAM_SIZE {
31 0
32 } else {
33 stream_size
34 },
35 is_nil: stream_size == NIL_STREAM_SIZE,
36 page_size: pdb.pages.page_size,
37 page_map,
38 file: &pdb.file,
39 pos,
40 }
41 }
42
43 pub fn len(&self) -> u32 {
47 self.stream_size
48 }
49
50 pub fn is_empty(&self) -> bool {
52 self.len() == 0
53 }
54
55 pub fn is_nil(&self) -> bool {
57 self.is_nil
58 }
59}
60
61impl<'a, F: ReadAt> Seek for StreamReader<'a, F> {
62 fn seek(&mut self, from: SeekFrom) -> std::io::Result<u64> {
63 let new_pos: i64 = match from {
64 SeekFrom::Start(offset) => offset as i64,
65 SeekFrom::End(signed_offset) => signed_offset + self.stream_size as i64,
66 SeekFrom::Current(signed_offset) => self.pos as i64 + signed_offset,
67 };
68
69 if new_pos < 0 {
70 return Err(std::io::ErrorKind::InvalidInput.into());
71 }
72 self.pos = new_pos as u64;
73 Ok(self.pos)
74 }
75}
76
77impl<'a, F: ReadAt> Read for StreamReader<'a, F> {
78 fn read(&mut self, dst: &mut [u8]) -> std::io::Result<usize> {
79 let (n, new_pos) = super::read::read_stream_core(
80 self.stream,
81 self.file,
82 self.page_size,
83 self.stream_size,
84 self.page_map,
85 self.pos,
86 dst,
87 )?;
88
89 self.pos = new_pos;
90 Ok(n)
91 }
92}
93
94impl<'a, F: ReadAt> ReadAt for StreamReader<'a, F> {
95 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<()> {
96 let (n, _new_pos) = super::read::read_stream_core(
97 self.stream,
98 self.file,
99 self.page_size,
100 self.stream_size,
101 self.page_map,
102 offset,
103 buf,
104 )?;
105 if n != buf.len() {
106 return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof));
107 }
108 Ok(())
109 }
110
111 fn read_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<usize> {
112 let (n, _new_pos) = super::read::read_stream_core(
113 self.stream,
114 self.file,
115 self.page_size,
116 self.stream_size,
117 self.page_map,
118 offset,
119 buf,
120 )?;
121 Ok(n)
122 }
123}