Skip to main content

ms_pdb/
embedded_sources.rs

1use super::*;
2use anyhow::Result;
3use std::io::Write;
4
5impl<F: ReadAt> Pdb<F> {
6    /// Embeds the contents of a source file into the PDB.
7    pub fn add_embedded_source(&mut self, file_path: &str, file_contents: &[u8]) -> Result<bool>
8    where
9        F: WriteAt,
10    {
11        let stream_name = format!("/src/{file_path}");
12        self.add_or_replace_named_stream(&stream_name, file_contents)
13    }
14
15    /// Sets the contents of a named stream to the given value.
16    ///
17    /// If there is already a named stream with the given name, then the stream's contents
18    /// are replaced with `stream_contents`.  First, though, this function reads the contents of
19    /// the existing stream and compares them to `stream_contents`. If they are identical, then
20    /// the stream is not modified and this function will return `Ok(true)`.  If the contents are
21    /// not identical, then this function returns `Ok(true)`.
22    ///
23    /// If there is not already a named stream with given name, then a new stream is created
24    /// and an entry is added to the Named Streams Map. In this case, the function returns
25    /// `Ok(false)`.
26    pub fn add_or_replace_named_stream(
27        &mut self,
28        stream_name: &str,
29        stream_contents: &[u8],
30    ) -> Result<bool>
31    where
32        F: WriteAt,
33    {
34        if let Some(existing_stream) = self.named_streams().get(stream_name) {
35            // No need to update the named stream directory.
36
37            // Are the stream contents identical?
38            let existing_len = self.stream_len(existing_stream);
39            if existing_len == stream_contents.len() as u64 {
40                let existing_contents = self.read_stream_to_vec(existing_stream)?;
41                if existing_contents == stream_contents {
42                    return Ok(false);
43                }
44            }
45
46            let mut w = self.msf_mut_err()?.write_stream(existing_stream)?;
47            w.set_len(0)?;
48            w.write_all(stream_contents)?;
49            Ok(true)
50        } else {
51            let (new_stream, mut w) = self.msf_mut_err()?.new_stream()?;
52            w.write_all(stream_contents)?;
53            self.named_streams_mut().insert(stream_name, new_stream);
54            Ok(true)
55        }
56    }
57}