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