hao 0.0.3

.net binary reader
Documentation
mod blob_stream;
pub mod tables_stream;
mod values_streams;
pub use blob_stream::*;
pub use values_streams::*;

use super::metadata_header::StreamHeader;
use crate::{
    error::{HaoError, Result},
    io::PEImage,
};
use tables_stream::TablesStreams;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Version(u8, u8);
impl Version {
    pub fn new(major_version: u8, minor_version: u8) -> Self {
        Self(major_version, minor_version)
    }
}

#[derive(Debug, Clone)]
pub struct MetadataStreams<'a> {
    pub tables_stream: TablesStreams<'a>,
    pub strings_stream: StringsStream<'a>,
    pub guid_stream: GuidStream<'a>,
    pub blob_stream: BlobStream<'a>,
}

impl<'a> MetadataStreams<'a> {
    pub fn from_headers(
        pe_image: &PEImage<'a>,
        streams: &[StreamHeader],
        metadata_virtual_address: u32,
    ) -> Result<Self> {
        let mut strings_stream = None;
        let mut tables_stream = None;
        let mut blob_stream = None;
        let mut guid_stream = None;

        for stream_header in streams {
            let stream_reader = pe_image.create_reader(
                metadata_virtual_address + stream_header.offset,
                Some(stream_header.stream_size as usize),
            )?;

            match stream_header.name.as_ref() {
                "#Strings" => strings_stream = Some(StringsStream::from_reader(stream_reader)?),
                "#US" => continue,
                "#Blob" => blob_stream = Some(BlobStream::from_reader(stream_reader)?),
                "#GUID" => guid_stream = Some(GuidStream::from_reader(stream_reader)?),
                "#~" => tables_stream = Some(TablesStreams::from_reader(stream_reader)?),
                "#Pdb" => continue,
                _ => {}
            }
        }

        Ok(Self {
            tables_stream: tables_stream
                .ok_or_else(|| HaoError::BadImageFormat("No .net tables stream (#~)"))?,
            strings_stream: strings_stream
                .ok_or_else(|| HaoError::BadImageFormat("No strings stream (#Strings)"))?,
            guid_stream: guid_stream
                .ok_or_else(|| HaoError::BadImageFormat("No guid stream (#GUID)"))?,
            blob_stream: blob_stream
                .ok_or_else(|| HaoError::BadImageFormat("No blob stream (#Blob)"))?,
        })
    }
}