use dbi;
use module_info;
use msf;
use symbol;
use tpi;
use pdbi;
use common::*;
use dbi::{DebugInformation, Module};
use module_info::ModuleInfo;
use source::Source;
use msf::{MSF, Stream};
use symbol::SymbolTable;
use tpi::TypeInformation;
use pdbi::PDBInformation;
const PDB_STREAM: u32 = 1;
const TPI_STREAM: u32 = 2;
const DBI_STREAM: u32 = 3;
#[allow(dead_code)]
const IPI_STREAM: u32 = 4;
#[derive(Debug)]
pub struct PDB<'s, S> {
msf: Box<MSF<'s, S> + 's>,
dbi_header: Option<dbi::Header>,
}
impl<'s, S: Source<'s> + 's> PDB<'s, S> {
pub fn open(source: S) -> Result<PDB<'s, S>> {
let msf = msf::open_msf(source)?;
Ok(PDB{
msf: msf,
dbi_header: None,
})
}
pub fn pdb_information(&mut self) -> Result<PDBInformation<'s>> {
let stream: Stream = self.msf.get(PDB_STREAM, None)?;
let pdb_info = pdbi::new_pdb_information(stream)?;
Ok(pdb_info)
}
pub fn type_information(&mut self) -> Result<TypeInformation<'s>> {
let stream: Stream = self.msf.get(TPI_STREAM, None)?;
let type_info = tpi::new_type_information(stream)?;
Ok(type_info)
}
pub fn debug_information(&mut self) -> Result<DebugInformation<'s>> {
let stream: Stream = self.msf.get(DBI_STREAM, None)?;
let debug_info = dbi::new_debug_information(stream)?;
self.dbi_header = Some(dbi::get_header(&debug_info));
Ok(debug_info)
}
fn dbi_header(&mut self) -> Result<dbi::Header> {
if let Some(ref h) = self.dbi_header {
return Ok(*h);
}
let header;
{
let stream: Stream = self.msf.get(DBI_STREAM, Some(1024))?;
let mut buf = stream.parse_buffer();
header = dbi::parse_header(&mut buf)?;
}
self.dbi_header = Some(header);
Ok(header)
}
pub fn global_symbols(&mut self) -> Result<SymbolTable<'s>> {
let dbi_header = self.dbi_header()?;
let stream: Stream = self.msf.get(dbi_header.symbol_records_stream as u32, None)?;
Ok(symbol::new_symbol_table(stream))
}
pub fn module_info<'m>(&mut self, module: &Module<'m>) -> Result<ModuleInfo<'s>> {
let res = {
let stream: Stream = self.msf.get(module.info().stream as u32, None)?;
module_info::new_module_info(stream, module)
};
res
}
pub fn raw_stream(&mut self, stream: u32) -> Result<Stream<'s>> {
self.msf.get(stream, None)
}
pub fn named_stream(&mut self, name: &[u8]) -> Result<Stream<'s>> {
let info = self.pdb_information()?;
let names = info.stream_names()?;
for n in names.iter() {
if n.name.as_bytes() == name {
return self.raw_stream(n.stream_id);
}
}
Err(Error::StreamNameNotFound)
}
}