Struct gimli::read::unit::EntriesCursor
source · pub struct EntriesCursor<'abbrev, 'unit, R>where
R: Reader,{
input: R,
unit: &'unit UnitHeader<R>,
abbreviations: &'abbrev Abbreviations,
cached_current: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>,
delta_depth: isize,
}
Expand description
A cursor into the Debugging Information Entries tree for a compilation unit.
The EntriesCursor
can traverse the DIE tree in DFS order using next_dfs()
,
or skip to the next sibling of the entry the cursor is currently pointing to
using next_sibling()
.
It is also possible to traverse the DIE tree at a lower abstraction level
using next_entry()
. This method does not skip over null entries, or provide
any indication of the current tree depth. In this case, you must use current()
to obtain the current entry, and current().has_children()
to determine if
the entry following the current entry will be a sibling or child. current()
will return None
if the current entry is a null entry, which signifies the
end of the current tree depth.
Fields§
§input: R
§unit: &'unit UnitHeader<R>
§abbreviations: &'abbrev Abbreviations
§cached_current: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>
§delta_depth: isize
Implementations§
source§impl<'abbrev, 'unit, R: Reader> EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R: Reader> EntriesCursor<'abbrev, 'unit, R>
sourcepub fn current(&self) -> Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>
pub fn current(&self) -> Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>
Get a reference to the entry that the cursor is currently pointing to.
If the cursor is not pointing at an entry, or if the current entry is a
null entry, then None
is returned.
sourcepub fn next_entry(&mut self) -> Result<Option<()>>
pub fn next_entry(&mut self) -> Result<Option<()>>
Move the cursor to the next DIE in the tree.
Returns Some
if there is a next entry, even if this entry is null.
If there is no next entry, then None
is returned.
sourcepub fn next_dfs(
&mut self,
) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>>
pub fn next_dfs( &mut self, ) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>>
Move the cursor to the next DIE in the tree in DFS order.
Upon successful movement of the cursor, return the delta traversal depth and the entry:
-
If we moved down into the previous current entry’s children, we get
Some((1, entry))
. -
If we moved to the previous current entry’s sibling, we get
Some((0, entry))
. -
If the previous entry does not have any siblings and we move up to its parent’s next sibling, then we get
Some((-1, entry))
. Note that if the parent doesn’t have a next sibling, then it could go up to the parent’s parent’s next sibling and returnSome((-2, entry))
, etc.
If there is no next entry, then None
is returned.
Here is an example that finds the first entry in a compilation unit that does not have any children.
let unit = get_some_unit();
let abbrevs = get_abbrevs_for_unit(&unit);
let mut first_entry_with_no_children = None;
let mut cursor = unit.entries(&abbrevs);
// Move the cursor to the root.
assert!(cursor.next_dfs().unwrap().is_some());
// Traverse the DIE tree in depth-first search order.
let mut depth = 0;
while let Some((delta_depth, current)) = cursor.next_dfs().expect("Should parse next dfs") {
// Update depth value, and break out of the loop when we
// return to the original starting position.
depth += delta_depth;
if depth <= 0 {
break;
}
first_entry_with_no_children = Some(current.clone());
}
println!("The first entry with no children is {:?}",
first_entry_with_no_children.unwrap());
sourcepub fn next_sibling(
&mut self,
) -> Result<Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>>
pub fn next_sibling( &mut self, ) -> Result<Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>>
Move the cursor to the next sibling DIE of the current one.
Returns Ok(Some(entry))
when the cursor has been moved to
the next sibling, Ok(None)
when there is no next sibling.
The depth of the cursor is never changed if this method returns Ok
.
Once Ok(None)
is returned, this method will continue to return
Ok(None)
until either next_entry
or next_dfs
is called.
Here is an example that iterates over all of the direct children of the root entry:
let unit = get_some_unit();
let abbrevs = get_abbrevs_for_unit(&unit);
let mut cursor = unit.entries(&abbrevs);
// Move the cursor to the root.
assert!(cursor.next_dfs().unwrap().is_some());
// Move the cursor to the root's first child.
assert!(cursor.next_dfs().unwrap().is_some());
// Iterate the root's children.
loop {
{
let current = cursor.current().expect("Should be at an entry");
println!("{:?} is a child of the root", current);
}
if cursor.next_sibling().expect("Should parse next sibling").is_none() {
break;
}
}
Trait Implementations§
source§impl<'abbrev, 'unit, R> Clone for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> Clone for EntriesCursor<'abbrev, 'unit, R>
source§fn clone(&self) -> EntriesCursor<'abbrev, 'unit, R>
fn clone(&self) -> EntriesCursor<'abbrev, 'unit, R>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl<'abbrev, 'unit, R> !Freeze for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> !RefUnwindSafe for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> Send for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> !Sync for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> Unpin for EntriesCursor<'abbrev, 'unit, R>
impl<'abbrev, 'unit, R> UnwindSafe for EntriesCursor<'abbrev, 'unit, R>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)