use std::borrow::Cow;
use std::ops::Deref;
use gimli;
use crate::file::FileHash;
use crate::function::Function;
use crate::range::RangeList;
use crate::types::Type;
use crate::variable::Variable;
#[derive(Debug, Default)]
pub struct Unit<'input> {
pub(crate) dir: Option<Cow<'input, str>>,
pub(crate) name: Option<Cow<'input, str>>,
pub(crate) language: Option<gimli::DwLang>,
pub(crate) address_size: Option<u64>,
pub(crate) low_pc: Option<u64>,
pub(crate) ranges: RangeList,
pub(crate) types: Vec<Type<'input>>,
pub(crate) functions: Vec<Function<'input>>,
pub(crate) variables: Vec<Variable<'input>>,
}
impl<'input> Unit<'input> {
pub fn dir(&self) -> Option<&str> {
self.dir.as_ref().map(Cow::deref)
}
pub fn name(&self) -> Option<&str> {
self.name.as_ref().map(Cow::deref)
}
#[inline]
pub fn language(&self) -> Option<gimli::DwLang> {
self.language
}
#[inline]
pub fn address(&self) -> Option<u64> {
self.low_pc
}
pub fn ranges(&self, hash: &FileHash) -> RangeList {
let mut ranges = RangeList::default();
for function in &self.functions {
if let Some(range) = function.range() {
ranges.push(range);
}
}
for variable in &self.variables {
if let Some(range) = variable.range(hash) {
ranges.push(range);
}
}
ranges.sort();
ranges
}
pub fn unknown_ranges(&self, hash: &FileHash) -> RangeList {
let mut ranges = RangeList::default();
for range in self.ranges.list() {
ranges.push(*range);
}
ranges.sort();
ranges.subtract(&self.ranges(hash))
}
pub fn size(&self, hash: &FileHash) -> u64 {
self.function_size() + self.variable_size(hash)
}
pub fn function_size(&self) -> u64 {
let mut ranges = RangeList::default();
for function in &self.functions {
if let Some(range) = function.range() {
ranges.push(range);
}
}
ranges.sort();
ranges.size()
}
pub fn variable_size(&self, hash: &FileHash) -> u64 {
let mut ranges = RangeList::default();
for variable in &self.variables {
if let Some(range) = variable.range(hash) {
ranges.push(range);
}
}
ranges.sort();
ranges.size()
}
#[inline]
pub fn types(&self) -> &[Type<'input>] {
&self.types
}
#[inline]
pub fn functions(&self) -> &[Function<'input>] {
&self.functions
}
#[inline]
pub fn variables(&self) -> &[Variable<'input>] {
&self.variables
}
}