use symbolic_common::Language;
use super::{raw, PortablePdbCache};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct LineInfo<'data> {
pub line: u32,
pub file_name: &'data str,
pub file_lang: Language,
}
impl<'data> PortablePdbCache<'data> {
pub fn lookup(&self, func_idx: u32, il_offset: u32) -> Option<LineInfo<'data>> {
let range = raw::Range {
func_idx,
il_offset,
};
let sl = match self.ranges.binary_search(&range) {
Ok(idx) => self.source_locations.get(idx)?,
Err(idx) => {
let idx = idx.checked_sub(1)?;
let range = self.ranges.get(idx)?;
if range.func_idx < func_idx {
return None;
}
self.source_locations.get(idx)?
}
};
let (file_name, file_lang) = self.get_file(sl.file_idx)?;
Some(LineInfo {
line: sl.line,
file_name,
file_lang,
})
}
fn get_file(&self, idx: u32) -> Option<(&'data str, Language)> {
let raw = self.files.get(idx as usize)?;
let name = self.get_string(raw.name_offset)?;
Some((name, Language::from_u32(raw.lang)))
}
fn get_string(&self, offset: u32) -> Option<&'data str> {
watto::StringTable::read(self.string_bytes, offset as usize).ok()
}
}