use crate::{
lldb_addr_t, sys, SBBlock, SBCompileUnit, SBFunction, SBLineEntry, SBModule, SBSection,
SBStream, SBSymbol, SBSymbolContext, SBTarget,
};
use std::fmt;
pub struct SBAddress {
pub raw: sys::SBAddressRef,
}
impl SBAddress {
pub fn maybe_wrap(raw: sys::SBAddressRef) -> Option<SBAddress> {
if unsafe { sys::SBAddressIsValid(raw) } {
Some(SBAddress { raw })
} else {
None
}
}
pub fn is_valid(&self) -> bool {
unsafe { sys::SBAddressIsValid(self.raw) }
}
pub fn from_section_offset(section: &SBSection, offset: lldb_addr_t) -> SBAddress {
let a = unsafe { sys::CreateSBAddress2(section.raw, offset) };
SBAddress::from(a)
}
pub fn from_load_address(load_addr: lldb_addr_t, target: &SBTarget) -> SBAddress {
let a = unsafe { sys::CreateSBAddress3(load_addr, target.raw) };
SBAddress::from(a)
}
pub fn file_address(&self) -> u64 {
unsafe { sys::SBAddressGetFileAddress(self.raw) }
}
pub fn load_address(&self, target: &SBTarget) -> u64 {
unsafe { sys::SBAddressGetLoadAddress(self.raw, target.raw) }
}
pub fn symbol_context(&self, resolve_scope: u32) -> SBSymbolContext {
SBSymbolContext::from(unsafe { sys::SBAddressGetSymbolContext(self.raw, resolve_scope) })
}
pub fn module(&self) -> Option<SBModule> {
SBModule::maybe_wrap(unsafe { sys::SBAddressGetModule(self.raw) })
}
pub fn compile_unit(&self) -> Option<SBCompileUnit> {
SBCompileUnit::maybe_wrap(unsafe { sys::SBAddressGetCompileUnit(self.raw) })
}
pub fn function(&self) -> Option<SBFunction> {
SBFunction::maybe_wrap(unsafe { sys::SBAddressGetFunction(self.raw) })
}
pub fn block(&self) -> Option<SBBlock> {
SBBlock::maybe_wrap(unsafe { sys::SBAddressGetBlock(self.raw) })
}
pub fn symbol(&self) -> Option<SBSymbol> {
SBSymbol::maybe_wrap(unsafe { sys::SBAddressGetSymbol(self.raw) })
}
pub fn line_entry(&self) -> Option<SBLineEntry> {
SBLineEntry::maybe_wrap(unsafe { sys::SBAddressGetLineEntry(self.raw) })
}
}
impl Clone for SBAddress {
fn clone(&self) -> SBAddress {
SBAddress {
raw: unsafe { sys::CloneSBAddress(self.raw) },
}
}
}
impl fmt::Debug for SBAddress {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let stream = SBStream::new();
unsafe { sys::SBAddressGetDescription(self.raw, stream.raw) };
write!(fmt, "SBAddress {{ {} }}", stream.data())
}
}
impl Drop for SBAddress {
fn drop(&mut self) {
unsafe { sys::DisposeSBAddress(self.raw) };
}
}
impl From<sys::SBAddressRef> for SBAddress {
fn from(raw: sys::SBAddressRef) -> SBAddress {
SBAddress { raw }
}
}
unsafe impl Send for SBAddress {}
unsafe impl Sync for SBAddress {}
impl PartialEq for SBAddress {
fn eq(&self, other: &Self) -> bool {
unsafe { sys::SBAddressIsEqual(self.raw, other.raw) }
}
}
impl Eq for SBAddress {}
#[cfg(feature = "graphql")]
graphql_object!(SBAddress: crate::SBDebugger | &self | {
field is_valid() -> bool {
self.is_valid()
}
field file_address() -> i32 {
self.file_address() as i32
}
field module() -> Option<SBModule> {
self.module()
}
field compile_unit() -> Option<SBCompileUnit> {
self.compile_unit()
}
field function() -> Option<SBFunction> {
self.function()
}
field block() -> Option<SBBlock> {
self.block()
}
field symbol() -> Option<SBSymbol> {
self.symbol()
}
field line_entry() -> Option<SBLineEntry> {
self.line_entry()
}
});
#[cfg(test)]
mod tests {
use super::SBAddress;
#[test]
fn test_equal() {
let sect = unsafe { sys::CreateSBSection() };
let a = SBAddress::maybe_wrap(unsafe { sys::CreateSBAddress2(sect, 42) }).unwrap();
let b = SBAddress::maybe_wrap(unsafe { sys::CreateSBAddress2(sect, 42) }).unwrap();
assert!(a == b);
}
#[test]
fn test_not_equal() {
let sect = unsafe { sys::CreateSBSection() };
let a = SBAddress::maybe_wrap(unsafe { sys::CreateSBAddress2(sect, 42) }).unwrap();
let b = SBAddress::maybe_wrap(unsafe { sys::CreateSBAddress2(sect, 111) }).unwrap();
assert!(a != b);
}
}