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}