[][src]Struct mozpdb::TypeInformation

pub struct TypeInformation<'t> { /* fields omitted */ }

TypeInformation provides zero-copy access to a PDB type data stream.

PDB type information is stored as a stream of length-prefixed Type records, and thus the most fundamental operation supported by TypeInformation is to iterate over Types.

Types are uniquely identified by TypeIndex, and types are stored within the PDB in ascending order of TypeIndex.

Many types refer to other types by TypeIndex, and these references may refer to other types forming a chain that's arbitrarily long. Fortunately, PDB format requires that types refer only to types with lower TypeIndexes; thus, the stream of types form a directed acyclic graph.

TypeInformation can iterate by TypeIndex, since that's essentially the only operation permitted by the data. TypeFinder is a secondary data structure to provide efficient backtracking.

Examples

Iterating over the types while building a TypeFinder:


let type_information = pdb.type_information()?;
let mut type_finder = type_information.new_type_finder();

let mut iter = type_information.iter();
while let Some(typ) = iter.next()? {
    // build the type finder as we go
    type_finder.update(&iter);

    // parse the type record
    match typ.parse() {
        Ok(pdb::TypeData::Class(pdb::ClassType {name, properties, fields: Some(fields), ..})) => {
            // this Type describes a class-like type with fields
            println!("type {} is a class named {}", typ.type_index(), name);

            // `fields` is a TypeIndex which refers to a FieldList
            // To find information about the fields, find and parse that Type
            match type_finder.find(fields)?.parse()? {
                pdb::TypeData::FieldList(list) => {
                    // `fields` is a Vec<TypeData>
                    for field in list.fields {
                        if let pdb::TypeData::Member(member) = field {
                            // follow `member.field_type` as desired
                            println!("  - field {} at offset {:x}", member.name, member.offset);
                        } else {
                            // handle member functions, nested types, etc.
                        }
                    }

                    if let Some(more_fields) = list.continuation {
                        // A FieldList can be split across multiple records
                        // TODO: follow `more_fields` and handle the next FieldList
                    }
                }
                _ => { }
            }

        },
        Ok(_) => {
            // ignore everything that's not a class-like type
        },
        Err(pdb::Error::UnimplementedTypeKind(_)) => {
            // found an unhandled type record
            // this probably isn't fatal in most use cases
        },
        Err(e) => {
            // other error, probably is worth failing
            return Err(e);
        }
    }
}

Methods

impl<'t> TypeInformation<'t>[src]

pub fn iter(&self) -> TypeIter[src]

Returns an iterator that can traverse the type table in sequential order.

pub fn len(&self) -> usize[src]

Returns the number of types contained in this TypeInformation.

Note that primitive types are not stored in the PDB file, so the number of distinct types reachable via this TypeInformation will be higher than len().

pub fn new_type_finder(&self) -> TypeFinder[src]

Returns a TypeFinder with a default time-space tradeoff.

The TypeFinder is initially empty and must be populated by iterating.

Trait Implementations

impl<'t> Debug for TypeInformation<'t>[src]

Auto Trait Implementations

impl<'t> !Send for TypeInformation<'t>

impl<'t> !Sync for TypeInformation<'t>

impl<'t> Unpin for TypeInformation<'t>

impl<'t> !UnwindSafe for TypeInformation<'t>

impl<'t> !RefUnwindSafe for TypeInformation<'t>

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]